From 3d0b5d5f6cc6cdf595a7c81b54dbf23d67fdd0db Mon Sep 17 00:00:00 2001 From: joyqi Date: Wed, 18 Aug 2021 22:29:34 +0800 Subject: [PATCH] reformat code --- var/AutoP.php | 146 +- var/Helper.php | 133 +- var/Json.php | 658 +++--- var/Markdown.php | 10 +- var/PasswordHash.php | 221 +- var/Typecho/Common.php | 907 ++++--- var/Typecho/Db/Adapter.php | 6 +- var/Typecho/Db/Adapter/Mysql.php | 46 +- var/Typecho/Db/Adapter/Mysqli.php | 44 +- var/Typecho/Db/Adapter/Pdo.php | 48 +- var/Typecho/Db/Adapter/Pdo/Mysql.php | 34 +- var/Typecho/Db/Adapter/Pdo/Pgsql.php | 43 +- var/Typecho/Db/Adapter/Pdo/SQLite.php | 50 +- var/Typecho/Db/Adapter/Pgsql.php | 81 +- var/Typecho/Db/Adapter/SQLite.php | 82 +- var/Typecho/Db/Query.php | 272 ++- var/Typecho/Http/Client.php | 12 +- var/Typecho/Http/Client/Adapter.php | 90 +- var/Typecho/Http/Client/Adapter/Curl.php | 2 +- var/Typecho/Http/Client/Adapter/Socket.php | 38 +- var/Typecho/I18n/GetText.php | 347 +-- var/Typecho/I18n/GetTextMulti.php | 10 +- var/Typecho/Response.php | 270 +-- var/Typecho/Router/Parser.php | 28 +- var/Typecho/Widget.php | 6 +- var/Typecho/Widget/Helper/Form.php | 106 +- var/Typecho/Widget/Helper/Form/Element.php | 210 +- .../Widget/Helper/Form/Element/Checkbox.php | 12 +- .../Widget/Helper/Form/Element/Fake.php | 7 +- .../Widget/Helper/Form/Element/Hidden.php | 4 +- .../Widget/Helper/Form/Element/Password.php | 6 +- .../Widget/Helper/Form/Element/Radio.php | 10 +- .../Widget/Helper/Form/Element/Select.php | 6 +- .../Widget/Helper/Form/Element/Submit.php | 4 +- .../Widget/Helper/Form/Element/Text.php | 6 +- .../Widget/Helper/Form/Element/Textarea.php | 4 +- var/Typecho/Widget/Helper/Layout.php | 193 +- var/Typecho/Widget/Helper/PageNavigator.php | 6 +- .../Widget/Helper/PageNavigator/Box.php | 34 +- .../Widget/Helper/PageNavigator/Classic.php | 4 +- var/Upgrade.php | 560 ++--- var/Widget/Abstract.php | 2 +- var/Widget/Abstract/Comments.php | 420 ++-- var/Widget/Abstract/Contents.php | 1072 ++++----- var/Widget/Abstract/Metas.php | 220 +- var/Widget/Abstract/Options.php | 28 +- var/Widget/Abstract/Users.php | 122 +- var/Widget/Ajax.php | 44 +- var/Widget/Archive.php | 2104 ++++++++--------- var/Widget/Backup.php | 299 +-- var/Widget/Comments/Admin.php | 40 +- var/Widget/Comments/Archive.php | 496 ++-- var/Widget/Comments/Edit.php | 224 +- var/Widget/Comments/Ping.php | 142 +- var/Widget/Comments/Recent.php | 14 +- var/Widget/Contents/Attachment/Admin.php | 38 +- var/Widget/Contents/Attachment/Edit.php | 184 +- var/Widget/Contents/Attachment/Related.php | 2 +- var/Widget/Contents/Attachment/Unattached.php | 4 +- var/Widget/Contents/Page/Admin.php | 8 +- var/Widget/Contents/Page/Edit.php | 66 +- var/Widget/Contents/Page/List.php | 8 +- var/Widget/Contents/Post/Admin.php | 70 +- var/Widget/Contents/Post/Date.php | 13 +- var/Widget/Contents/Post/Edit.php | 1202 +++++----- var/Widget/Contents/Post/Recent.php | 12 +- var/Widget/Contents/Related.php | 46 +- var/Widget/Contents/Related/Author.php | 16 +- var/Widget/Do.php | 52 +- var/Widget/Feedback.php | 302 +-- var/Widget/Init.php | 2 +- var/Widget/Interface/Do.php | 1 + var/Widget/Login.php | 8 +- var/Widget/Logout.php | 2 +- var/Widget/Menu.php | 219 +- var/Widget/Metas/Category/Admin.php | 14 +- var/Widget/Metas/Category/Edit.php | 157 +- var/Widget/Metas/Category/List.php | 396 ++-- var/Widget/Metas/Tag/Admin.php | 2 +- var/Widget/Metas/Tag/Cloud.php | 8 +- var/Widget/Metas/Tag/Edit.php | 190 +- var/Widget/Notice.php | 8 +- var/Widget/Options.php | 660 +++--- var/Widget/Options/Discussion.php | 206 +- var/Widget/Options/General.php | 316 +-- var/Widget/Options/Permalink.php | 320 +-- var/Widget/Options/Reading.php | 264 +-- var/Widget/Plugins/Config.php | 22 +- var/Widget/Plugins/Edit.php | 208 +- var/Widget/Plugins/List.php | 116 +- var/Widget/Register.php | 23 +- var/Widget/Security.php | 98 +- var/Widget/Service.php | 94 +- var/Widget/Stat.php | 184 +- var/Widget/Themes/Config.php | 12 +- var/Widget/Themes/Edit.php | 72 +- var/Widget/Themes/Files.php | 16 +- var/Widget/Themes/List.php | 46 +- var/Widget/Upgrade.php | 2 +- var/Widget/Upload.php | 648 ++--- var/Widget/User.php | 206 +- var/Widget/Users/Admin.php | 66 +- var/Widget/Users/Author.php | 2 +- var/Widget/Users/Edit.php | 264 ++- var/Widget/Users/Profile.php | 310 +-- var/Widget/XmlRpc.php | 1908 ++++++++------- 106 files changed, 9528 insertions(+), 9548 deletions(-) diff --git a/var/AutoP.php b/var/AutoP.php index dd6fb847..0efd0b1b 100644 --- a/var/AutoP.php +++ b/var/AutoP.php @@ -1,10 +1,10 @@ + * @author Joyqi * @license GNU General Public License 2.0 */ class AutoP @@ -14,34 +14,62 @@ class AutoP /** * 唯一id - * + * * @access private * @var integer */ private $_uniqueId = 0; - + /** * 存储的段落 - * + * * @access private * @var array */ - private $_blocks = array(); + private $_blocks = []; /** - * 生成唯一的id, 为了速度考虑最多支持1万个tag的处理 - * - * @access private + * 替换段落的回调函数 + * + * @access public + * @param array $matches 匹配值 * @return string */ - private function makeUniqueId() + public function replaceBlockCallback($matches) { - return ':' . str_pad($this->_uniqueId ++, 4, '0', STR_PAD_LEFT); + $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|ins|h1|h2|h3|h4|h5|h6|', $tagMatch): + $text = nl2br(trim($text)); + break; + /** 用段落处理换行 */ + case false !== strpos('|div|blockquote|form|', $tagMatch): + $text = $this->cutByBlock($text); + if (false !== strpos($text, '

')) { + $text = $this->fixPragraph($text); + } + break; + default: + break; + } + + /** 没有段落能力的标签 */ + if (false !== strpos('|a|span|font|code|cite|strong|sup|sub|small|del|u|i|b|', $tagMatch)) { + $key = ''; + } else { + $key = ''; + } + + $this->_blocks[$key] = "<{$matches[1]}{$matches[3]}>{$text}"; + return $key; } /** * 用段落方法处理换行 - * + * * @access private * @param string $text * @return string @@ -63,7 +91,7 @@ class AutoP /** * 修复段落开头和结尾 - * + * * @access private * @param string $text * @return string @@ -74,57 +102,18 @@ class AutoP if (!preg_match("/^<(" . self::BLOCK . ")(\s|>)/i", $text)) { $text = '

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

'; } - + return $text; } /** - * 替换段落的回调函数 - * - * @access public - * @param array $matches 匹配值 - * @return string - */ - public 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|ins|h1|h2|h3|h4|h5|h6|', $tagMatch): - $text = nl2br(trim($text)); - break; - /** 用段落处理换行 */ - case false !== strpos('|div|blockquote|form|', $tagMatch): - $text = $this->cutByBlock($text); - if (false !== strpos($text, '

')) { - $text = $this->fixPragraph($text); - } - break; - default: - break; - } - - /** 没有段落能力的标签 */ - if (false !== strpos('|a|span|font|code|cite|strong|sup|sub|small|del|u|i|b|', $tagMatch)) { - $key = ''; - } else { - $key = ''; - } - - $this->_blocks[$key] = "<{$matches[1]}{$matches[3]}>{$text}"; - return $key; - } - - /** - * 自动分段 - * - * @param string $text + * 自动分段 + * + * @param string $text * @static * @access private * @return string @@ -133,25 +122,25 @@ class AutoP { /** 重置计数器 */ $this->_uniqueId = 0; - $this->_blocks = array(); - + $this->_blocks = []; + /** 将已有的段落后面的换行处理掉 */ - $text = preg_replace(array("/<\/p>\s+\s*/is"), array("

"), trim($text)); - + $text = preg_replace(["/<\/p>\s+\s*/is"], ["

"], trim($text)); + /** 将所有非自闭合标签解析为唯一的字符串 */ $foundTagCount = 0; $textLength = strlen($text); - $uniqueIdList = array(); + $uniqueIdList = []; 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); @@ -165,32 +154,43 @@ class AutoP default: break; } - + if (false !== $pos) { $uniqueId = $this->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($this, 'replaceBlockCallback'), $text, 1); + [$this, 'replaceBlockCallback'], $text, 1); } - + $text = $this->cutByBlock($text); $blocks = array_reverse($this->_blocks); - + foreach ($blocks as $blockKey => $blockValue) { $text = str_replace($blockKey, $blockValue, $text); } - - return $this->fixPragraph($text); + + return $this->fixPragraph($text); + } + + /** + * 生成唯一的id, 为了速度考虑最多支持1万个tag的处理 + * + * @access private + * @return string + */ + private function makeUniqueId() + { + return ':' . str_pad($this->_uniqueId ++, 4, '0', STR_PAD_LEFT); } } diff --git a/var/Helper.php b/var/Helper.php index 037997eb..89cb1054 100644 --- a/var/Helper.php +++ b/var/Helper.php @@ -1,4 +1,5 @@ 'cid', - 'Comments' => 'coid', - 'Metas' => 'mid', - 'Users' => 'uid' - ); + $keys = [ + 'Contents' => 'cid', + 'Comments' => 'coid', + 'Metas' => 'mid', + 'Users' => 'uid' + ]; $className = "Widget_Abstract_{$table}"; $key = $keys[$table]; $db = Typecho_Db::get(); $widget = new $className(Typecho_Request::getInstance(), Typecho_Widget_Helper_Empty::getInstance()); - + $db->fetchRow( $widget->select()->where("{$key} = ?", $pkId)->limit(1), - array($widget, 'push')); + [$widget, 'push']); return $widget; } @@ -85,7 +75,7 @@ class Helper { try { /** 获取插件入口 */ - list($pluginFileName, $className) = Typecho_Plugin::portal($pluginName, __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__); + [$pluginFileName, $className] = Typecho_Plugin::portal($pluginName, __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__); /** 获取已启用插件 */ $plugins = Typecho_Plugin::export(); @@ -96,11 +86,11 @@ class Helper /** 判断实例化是否成功 */ if (!isset($activatedPlugins[$pluginName]) || !class_exists($className) - || !method_exists($className, 'deactivate')) { + || !method_exists($className, 'deactivate')) { throw new Typecho_Widget_Exception(_t('无法禁用插件'), 500); } - $result = call_user_func(array($className, 'deactivate')); + $result = call_user_func([$className, 'deactivate']); } catch (Exception $e) { //nothing to do @@ -111,8 +101,8 @@ class Helper try { Typecho_Plugin::deactivate($pluginName); $db->query($db->update('table.options') - ->rows(array('value' => serialize(Typecho_Plugin::export()))) - ->where('name = ?', 'plugins')); + ->rows(['value' => serialize(Typecho_Plugin::export())]) + ->where('name = ?', 'plugins')); } catch (Typecho_Plugin_Exception $e) { //nothing to do } @@ -150,7 +140,7 @@ class Helper * @param string $after 在某个路由后面 * @return integer */ - public static function addRoute($name, $url, $widget, $action = NULL, $after = NULL) + public static function addRoute($name, $url, $widget, $action = null, $after = null) { $routingTable = self::options()->routingTable; if (isset($routingTable[0])) { @@ -169,16 +159,27 @@ class Helper $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); + $routingTable = array_merge($pre, [$name => [ + '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')); + return Typecho_Widget::widget('Widget_Abstract_Options')->update(['value' => serialize($routingTable)] + , $db->sql()->where('name = ?', 'routingTable')); + } + + /** + * 获取Widget_Options对象 + * + * @access public + * @return Widget_Options + */ + public static function options() + { + return Typecho_Widget::widget('Widget_Options'); } /** @@ -199,8 +200,8 @@ class Helper 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')); + return Typecho_Widget::widget('Widget_Abstract_Options')->update(['value' => serialize($routingTable)] + , $db->sql()->where('name = ?', 'routingTable')); } /** @@ -214,12 +215,12 @@ class Helper public static function addAction($actionName, $widgetName) { $actionTable = unserialize(self::options()->actionTable); - $actionTable = empty($actionTable) ? array() : $actionTable; + $actionTable = empty($actionTable) ? [] : $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')); + return Typecho_Widget::widget('Widget_Abstract_Options')->update(['value' => (self::options()->actionTable = serialize($actionTable))] + , $db->sql()->where('name = ?', 'actionTable')); } /** @@ -232,7 +233,7 @@ class Helper public static function removeAction($actionName) { $actionTable = unserialize(self::options()->actionTable); - $actionTable = empty($actionTable) ? array() : $actionTable; + $actionTable = empty($actionTable) ? [] : $actionTable; if (isset($actionTable[$actionName])) { unset($actionTable[$actionName]); @@ -240,8 +241,8 @@ class Helper } $db = Typecho_Db::get(); - return Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->actionTable = serialize($actionTable))) - , $db->sql()->where('name = ?', 'actionTable')); + return Typecho_Widget::widget('Widget_Abstract_Options')->update(['value' => (self::options()->actionTable = serialize($actionTable))] + , $db->sql()->where('name = ?', 'actionTable')); } /** @@ -254,12 +255,12 @@ class Helper public static function addMenu($menuName) { $panelTable = unserialize(self::options()->panelTable); - $panelTable['parent'] = empty($panelTable['parent']) ? array() : $panelTable['parent']; + $panelTable['parent'] = empty($panelTable['parent']) ? [] : $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')); + Typecho_Widget::widget('Widget_Abstract_Options')->update(['value' => (self::options()->panelTable = serialize($panelTable))] + , $db->sql()->where('name = ?', 'panelTable')); end($panelTable['parent']); return key($panelTable['parent']) + 10; @@ -275,15 +276,15 @@ class Helper public static function removeMenu($menuName) { $panelTable = unserialize(self::options()->panelTable); - $panelTable['parent'] = empty($panelTable['parent']) ? array() : $panelTable['parent']; + $panelTable['parent'] = empty($panelTable['parent']) ? [] : $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')); + Typecho_Widget::widget('Widget_Abstract_Options')->update(['value' => (self::options()->panelTable = serialize($panelTable))] + , $db->sql()->where('name = ?', 'panelTable')); return $index + 10; } @@ -304,18 +305,18 @@ class Helper 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]; + $panelTable['child'] = empty($panelTable['child']) ? [] : $panelTable['child']; + $panelTable['child'][$index] = empty($panelTable['child'][$index]) ? [] : $panelTable['child'][$index]; $fileName = urlencode(trim($fileName, '/')); - $panelTable['child'][$index][] = array($title, $subTitle, 'extending.php?panel=' . $fileName, $level, $hidden, $addLink); + $panelTable['child'][$index][] = [$title, $subTitle, 'extending.php?panel=' . $fileName, $level, $hidden, $addLink]; - $panelTable['file'] = empty($panelTable['file']) ? array() : $panelTable['file']; + $panelTable['file'] = empty($panelTable['file']) ? [] : $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')); + Typecho_Widget::widget('Widget_Abstract_Options')->update(['value' => (self::options()->panelTable = serialize($panelTable))] + , $db->sql()->where('name = ?', 'panelTable')); end($panelTable['child'][$index]); return key($panelTable['child'][$index]); @@ -332,9 +333,9 @@ class Helper 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']; + $panelTable['child'] = empty($panelTable['child']) ? [] : $panelTable['child']; + $panelTable['child'][$index] = empty($panelTable['child'][$index]) ? [] : $panelTable['child'][$index]; + $panelTable['file'] = empty($panelTable['file']) ? [] : $panelTable['file']; $fileName = urlencode(trim($fileName, '/')); if (false !== ($key = array_search($fileName, $panelTable['file']))) { @@ -350,8 +351,8 @@ class Helper } $db = Typecho_Db::get(); - Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->panelTable = serialize($panelTable))) - , $db->sql()->where('name = ?', 'panelTable')); + Typecho_Widget::widget('Widget_Abstract_Options')->update(['value' => (self::options()->panelTable = serialize($panelTable))] + , $db->sql()->where('name = ?', 'panelTable')); return $return; } @@ -366,15 +367,15 @@ class Helper { return Typecho_Common::url('extending.php?panel=' . (trim($fileName, '/')), self::options()->adminUrl); } - + /** * 手动配置插件变量 - * + * * @access public * @static * @param mixed $pluginName 插件名称 * @param array $settings 变量键值对 - * @param bool $isPersonal. (default: false) 是否为私人变量 + * @param bool $isPersonal . (default: false) 是否为私人变量 * @return void */ public static function configPlugin($pluginName, array $settings, $isPersonal = false) @@ -382,7 +383,7 @@ class Helper if (empty($settings)) { return; } - + Widget_Plugins_Edit::configPlugin($pluginName, $settings, $isPersonal); } @@ -401,7 +402,7 @@ class Helper { if (self::options()->commentsThreaded) { echo '' . $word . ''; + $theId . '\', ' . $coid . ', \'' . $formId . '\', ' . $style . ');">' . $word . ''; } } @@ -417,7 +418,7 @@ class Helper { if (self::options()->commentsThreaded) { echo '' . $word . ''; + $formId . '\');">' . $word . ''; } } @@ -431,7 +432,7 @@ class Helper { if (self::options()->commentsThreaded) { echo -<< var typechoAddCommentReply = function (cid, coid, cfid, style) { var _ce = document.getElementById(cid), _cp = _ce.parentNode; diff --git a/var/Json.php b/var/Json.php index 5ed03b02..158bc7d1 100644 --- a/var/Json.php +++ b/var/Json.php @@ -18,98 +18,22 @@ class Json const E_JSONTYPE = 'json decode error'; /** - * 将utf16转换为utf8 + * 对配对值编码 * - * @access private - * @param string $utf16 utf16字符串 + * @access public + * @param string $name 名称 + * @param mixed $value 值 * @return string */ - private static function utf162utf8($utf16) + public static function _name_value($name, $value) { - if (function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); - } - $bytes = (ord($utf16[0]) << 8) | ord($utf16[1]); + $encoded_value = self::_encode($value); - switch (true) { - case ((0x7F & $bytes) == $bytes): - return chr(0x7F & $bytes); - - case (0x07FF & $bytes) == $bytes: - return chr(0xC0 | (($bytes >> 6) & 0x1F)) - . chr(0x80 | ($bytes & 0x3F)); - - case (0xFFFF & $bytes) == $bytes: - return chr(0xE0 | (($bytes >> 12) & 0x0F)) - . chr(0x80 | (($bytes >> 6) & 0x3F)) - . chr(0x80 | ($bytes & 0x3F)); - } - return ''; - } - - /** - * 将utf8转换为utf16 - * - * @access private - * @param string $utf8 utf8字符串 - * @return string - */ - private static function utf82utf16($utf8) - { - if (function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + if (self::_is_error($encoded_value)) { + return $encoded_value; } - switch (strlen($utf8)) { - case 1: - return $utf8; - - case 2: - return chr(0x07 & (ord($utf8[0]) >> 2)) - . chr((0xC0 & (ord($utf8[0]) << 6)) - | (0x3F & ord($utf8[1]))); - case 3: - return chr((0xF0 & (ord($utf8[0]) << 4)) - | (0x0F & (ord($utf8[1]) >> 2))) - . chr((0xC0 & (ord($utf8[1]) << 6)) - | (0x7F & ord($utf8[2]))); - } - return ''; - } - - /** - * 判断错误 - * - * @access private - * @param mixed $data 错误对象 - * @param string $code 错误代码 - * @return boolean - */ - private static function _is_error($data, $code = null) - { - if (is_object($data) && (get_class($data) == 'services_json_error' || - is_subclass_of($data, 'services_json_error'))) { - return true; - } - - return false; - } - - /** - * 清除特殊格式 - * - * @access private - * @param string $str 待处理字符串 - * @return string - */ - private static function _reduce_string($str) - { - $str = preg_replace(array( - '#^\s*//(.+)$#m', - '#^\s*/\*(.+)\*/#Us', - '#/\*(.+)\*/\s*$#Us' - ), '', $str); - return trim($str); + return self::_encode(strval($name)) . ':' . $encoded_value; } /** @@ -129,17 +53,17 @@ class Json return 'null'; case 'integer': - return (int) $var; + return (int)$var; case 'double': case 'float': - return (float) $var; + return (float)$var; case 'string': $ascii = ''; $strlen_var = strlen($var); - for ($c = 0; $c < $strlen_var; ++$c) { + for ($c = 0; $c < $strlen_var; ++ $c) { $ord_var_c = ord($var[$c]); @@ -163,7 +87,7 @@ class Json case $ord_var_c == 0x22: case $ord_var_c == 0x2F: case $ord_var_c == 0x5C: - $ascii .= '\\'.$var[$c]; + $ascii .= '\\' . $var[$c]; break; case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): @@ -179,8 +103,8 @@ class Json case (($ord_var_c & 0xF0) == 0xE0): $char = pack('C*', $ord_var_c, - ord($var[$c + 1]), - ord($var[$c + 2])); + ord($var[$c + 1]), + ord($var[$c + 2])); $c += 2; $utf16 = self::utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); @@ -188,9 +112,9 @@ class Json case (($ord_var_c & 0xF8) == 0xF0): $char = pack('C*', $ord_var_c, - ord($var[$c + 1]), - ord($var[$c + 2]), - ord($var[$c + 3])); + ord($var[$c + 1]), + ord($var[$c + 2]), + ord($var[$c + 3])); $c += 3; $utf16 = self::utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); @@ -198,10 +122,10 @@ class Json case (($ord_var_c & 0xFC) == 0xF8): $char = pack('C*', $ord_var_c, - ord($var[$c + 1]), - ord($var[$c + 2]), - ord($var[$c + 3]), - ord($var[$c + 4])); + ord($var[$c + 1]), + ord($var[$c + 2]), + ord($var[$c + 3]), + ord($var[$c + 4])); $c += 4; $utf16 = self::utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); @@ -209,11 +133,11 @@ class Json case (($ord_var_c & 0xFE) == 0xFC): $char = pack('C*', $ord_var_c, - ord($var[$c + 1]), - ord($var[$c + 2]), - ord($var[$c + 3]), - ord($var[$c + 4]), - ord($var[$c + 5])); + ord($var[$c + 1]), + ord($var[$c + 2]), + ord($var[$c + 3]), + ord($var[$c + 4]), + ord($var[$c + 5])); $c += 5; $utf16 = self::utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); @@ -221,13 +145,13 @@ class Json } } - return '"'.$ascii.'"'; + return '"' . $ascii . '"'; case 'array': if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - $properties = array_map(array('Json', '_name_value'), - array_keys($var), - array_values($var)); + $properties = array_map(['Json', '_name_value'], + array_keys($var), + array_values($var)); foreach ($properties as $property) { if (self::_is_error($property)) { @@ -239,7 +163,7 @@ class Json } // treat it like a regular array - $elements = array_map(array('Json', '_encode'), $var); + $elements = array_map(['Json', '_encode'], $var); foreach ($elements as $element) { if (self::_is_error($element)) { @@ -252,9 +176,9 @@ class Json case 'object': $vars = get_object_vars($var); - $properties = array_map(array('Json', '_name_value'), - array_keys($vars), - array_values($vars)); + $properties = array_map(['Json', '_name_value'], + array_keys($vars), + array_values($vars)); foreach ($properties as $property) { if (self::_is_error($property)) { @@ -270,233 +194,51 @@ class Json } /** - * 解码json字符串 + * 将utf8转换为utf16 * - * @access public - * @param string $str 解码字符串 - * @return mixed + * @access private + * @param string $utf8 utf8字符串 + * @return string */ - public static function _decode($str) + private static function utf82utf16($utf8) { - $str = self::_reduce_string($str); - - switch (strtolower($str)) { - case 'true': - return true; - - case 'false': - return false; - - case 'null': - return null; - - default: - $m = array(); - - if (is_numeric($str)) { - return ((float)$str == (integer)$str) - ? (integer)$str - : (float)$str; - - } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { - $delim = substr($str, 0, 1); - $chrs = substr($str, 1, -1); - $utf8 = ''; - $strlen_chrs = strlen($chrs); - - for ($c = 0; $c < $strlen_chrs; ++$c) { - - $substr_chrs_c_2 = substr($chrs, $c, 2); - $ord_chrs_c = ord($chrs[$c]); - - switch (true) { - case $substr_chrs_c_2 == '\b': - $utf8 .= chr(0x08); - ++$c; - break; - case $substr_chrs_c_2 == '\t': - $utf8 .= chr(0x09); - ++$c; - break; - case $substr_chrs_c_2 == '\n': - $utf8 .= chr(0x0A); - ++$c; - break; - case $substr_chrs_c_2 == '\f': - $utf8 .= chr(0x0C); - ++$c; - break; - case $substr_chrs_c_2 == '\r': - $utf8 .= chr(0x0D); - ++$c; - break; - - case $substr_chrs_c_2 == '\\"': - case $substr_chrs_c_2 == '\\\'': - case $substr_chrs_c_2 == '\\\\': - case $substr_chrs_c_2 == '\\/': - if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || - ($delim == "'" && $substr_chrs_c_2 != '\\"')) { - $utf8 .= $chrs[++$c]; - } - break; - - case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): - $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) - . chr(hexdec(substr($chrs, ($c + 4), 2))); - $utf8 .= self::utf162utf8($utf16); - $c += 5; - break; - - case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): - $utf8 .= $chrs[$c]; - break; - - case ($ord_chrs_c & 0xE0) == 0xC0: - $utf8 .= substr($chrs, $c, 2); - ++$c; - break; - - case ($ord_chrs_c & 0xF0) == 0xE0: - $utf8 .= substr($chrs, $c, 3); - $c += 2; - break; - - case ($ord_chrs_c & 0xF8) == 0xF0: - $utf8 .= substr($chrs, $c, 4); - $c += 3; - break; - - case ($ord_chrs_c & 0xFC) == 0xF8: - $utf8 .= substr($chrs, $c, 5); - $c += 4; - break; - - case ($ord_chrs_c & 0xFE) == 0xFC: - $utf8 .= substr($chrs, $c, 6); - $c += 5; - break; - - } - - } - - return $utf8; - - } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { - if ($str [0] == '[') { - $stk = array(self::SERVICES_JSON_IN_ARR); - $arr = array(); - } else { - $stk = array(self::SERVICES_JSON_IN_OBJ); - $obj = new stdClass(); - } - - array_push($stk, array('what' => self::SERVICES_JSON_SLICE, - 'where' => 0, - 'delim' => false)); - - $chrs = substr($str, 1, -1); - $chrs = self::_reduce_string($chrs); - - if ($chrs == '') { - if (reset($stk) == self::SERVICES_JSON_IN_ARR) { - return $arr; - - } else { - return $obj; - - } - } - - $strlen_chrs = strlen($chrs); - for ($c = 0; $c <= $strlen_chrs; ++$c) { - - $top = end($stk); - $substr_chrs_c_2 = substr($chrs, $c, 2); - - if (($c == $strlen_chrs) || (($chrs [$c] == ',') && ($top['what'] == self::SERVICES_JSON_SLICE))) { - $slice = substr($chrs, $top['where'], ($c - $top['where'])); - array_push($stk, array('what' => self::SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); - - if (reset($stk) == self::SERVICES_JSON_IN_ARR) { - array_push($arr, self::_decode($slice)); - - } elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) { - $parts = array(); - - if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - $key = self::_decode($parts[1]); - $val = self::_decode($parts[2]); - $obj->$key = $val; - } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - $key = $parts[1]; - $val = self::_decode($parts[2]); - $obj->$key = $val; - } - - } - - } elseif ((($chrs [$c] == '"') || ($chrs[$c] == "'")) && ($top['what'] != self::SERVICES_JSON_IN_STR)) { - array_push($stk, array('what' => self::SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs[$c])); - - } elseif (($chrs [$c] == $top['delim']) && - ($top['what'] == self::SERVICES_JSON_IN_STR) && - ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { - array_pop($stk); - - } elseif (($chrs [$c] == '[') && - in_array($top['what'], array(self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ))) { - array_push($stk, array('what' => self::SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); - } elseif (($chrs [$c] == ']') && ($top['what'] == self::SERVICES_JSON_IN_ARR)) { - array_pop($stk); - } elseif (($chrs [$c] == '{') && - in_array($top['what'], array(self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ))) { - array_push($stk, array('what' => self::SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); - } elseif (($chrs [$c] == '}') && ($top['what'] == self::SERVICES_JSON_IN_OBJ)) { - array_pop($stk); - } elseif (($substr_chrs_c_2 == '/*') && - in_array($top['what'], array(self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ))) { - array_push($stk, array('what' => self::SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); - $c++; - } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::SERVICES_JSON_IN_CMT)) { - array_pop($stk); - $c++; - for ($i = $top['where']; $i <= $c; ++$i) - $chrs = substr_replace($chrs, ' ', $i, 1); - } - - } - - if (reset($stk) == self::SERVICES_JSON_IN_ARR) { - return $arr; - - } elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) { - return $obj; - - } - - } + if (function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); } + + switch (strlen($utf8)) { + case 1: + return $utf8; + + case 2: + return chr(0x07 & (ord($utf8[0]) >> 2)) + . chr((0xC0 & (ord($utf8[0]) << 6)) + | (0x3F & ord($utf8[1]))); + case 3: + return chr((0xF0 & (ord($utf8[0]) << 4)) + | (0x0F & (ord($utf8[1]) >> 2))) + . chr((0xC0 & (ord($utf8[1]) << 6)) + | (0x7F & ord($utf8[2]))); + } + return ''; } /** - * 对配对值编码 + * 判断错误 * - * @access public - * @param string $name 名称 - * @param mixed $value 值 - * @return string + * @access private + * @param mixed $data 错误对象 + * @param string $code 错误代码 + * @return boolean */ - public static function _name_value($name, $value) + private static function _is_error($data, $code = null) { - $encoded_value = self::_encode($value); - - if (self::_is_error($encoded_value)) { - return $encoded_value; + if (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; } - return self::_encode(strval($name)) . ':' . $encoded_value; + return false; } /** @@ -534,12 +276,270 @@ class Json } if ($assoc && is_object($result)) { - return (array) $result; - } else if (!$assoc && is_array($result)) { - return (object) $result; + return (array)$result; + } elseif (!$assoc && is_array($result)) { + return (object)$result; } return $result; } + + /** + * 解码json字符串 + * + * @access public + * @param string $str 解码字符串 + * @return mixed + */ + public static function _decode($str) + { + $str = self::_reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = []; + + if (is_numeric($str)) { + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, - 1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++ $c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs[$c]); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++ $c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++ $c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++ $c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++ $c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++ $c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs[++ $c]; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= self::utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs[$c]; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + $utf8 .= substr($chrs, $c, 2); + ++ $c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + $utf8 .= substr($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + $utf8 .= substr($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + $utf8 .= substr($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + $utf8 .= substr($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + if ($str [0] == '[') { + $stk = [self::SERVICES_JSON_IN_ARR]; + $arr = []; + } else { + $stk = [self::SERVICES_JSON_IN_OBJ]; + $obj = new stdClass(); + } + + array_push($stk, ['what' => self::SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false]); + + $chrs = substr($str, 1, - 1); + $chrs = self::_reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == self::SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + $strlen_chrs = strlen($chrs); + for ($c = 0; $c <= $strlen_chrs; ++ $c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs [$c] == ',') && ($top['what'] == self::SERVICES_JSON_SLICE))) { + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, ['what' => self::SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false]); + + if (reset($stk) == self::SERVICES_JSON_IN_ARR) { + array_push($arr, self::_decode($slice)); + + } elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) { + $parts = []; + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + $key = self::_decode($parts[1]); + $val = self::_decode($parts[2]); + $obj->$key = $val; + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + $key = $parts[1]; + $val = self::_decode($parts[2]); + $obj->$key = $val; + } + + } + + } elseif ((($chrs [$c] == '"') || ($chrs[$c] == "'")) && ($top['what'] != self::SERVICES_JSON_IN_STR)) { + array_push($stk, ['what' => self::SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs[$c]]); + + } elseif (($chrs [$c] == $top['delim']) && + ($top['what'] == self::SERVICES_JSON_IN_STR) && + ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { + array_pop($stk); + + } elseif (($chrs [$c] == '[') && + in_array($top['what'], [self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ])) { + array_push($stk, ['what' => self::SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false]); + } elseif (($chrs [$c] == ']') && ($top['what'] == self::SERVICES_JSON_IN_ARR)) { + array_pop($stk); + } elseif (($chrs [$c] == '{') && + in_array($top['what'], [self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ])) { + array_push($stk, ['what' => self::SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false]); + } elseif (($chrs [$c] == '}') && ($top['what'] == self::SERVICES_JSON_IN_OBJ)) { + array_pop($stk); + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], [self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ])) { + array_push($stk, ['what' => self::SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false]); + $c ++; + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::SERVICES_JSON_IN_CMT)) { + array_pop($stk); + $c ++; + for ($i = $top['where']; $i <= $c; ++ $i) + $chrs = substr_replace($chrs, ' ', $i, 1); + } + + } + + if (reset($stk) == self::SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * 清除特殊格式 + * + * @access private + * @param string $str 待处理字符串 + * @return string + */ + private static function _reduce_string($str) + { + $str = preg_replace([ + '#^\s*//(.+)$#m', + '#^\s*/\*(.+)\*/#Us', + '#/\*(.+)\*/\s*$#Us' + ], '', $str); + return trim($str); + } + + /** + * 将utf16转换为utf8 + * + * @access private + * @param string $utf16 utf16字符串 + * @return string + */ + private static function utf162utf8($utf16) + { + if (function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + $bytes = (ord($utf16[0]) << 8) | ord($utf16[1]); + + switch (true) { + case ((0x7F & $bytes) == $bytes): + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + return ''; + } } diff --git a/var/Markdown.php b/var/Markdown.php index 63d985d6..ee10bbf3 100644 --- a/var/Markdown.php +++ b/var/Markdown.php @@ -11,9 +11,9 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; class Markdown { /** - * convert - * - * @param string $text + * convert + * + * @param string $text * @return string */ public static function convert($text) @@ -35,7 +35,7 @@ class Markdown /** * transerCodeClass - * + * * @param string $html * @return string */ @@ -50,7 +50,7 @@ class Markdown */ public static function transerComment($html) { - return preg_replace_callback("//s", array('Markdown', 'transerCommentCallback'), $html); + return preg_replace_callback("//s", ['Markdown', 'transerCommentCallback'], $html); } /** diff --git a/var/PasswordHash.php b/var/PasswordHash.php index dac979b6..0c45faa3 100644 --- a/var/PasswordHash.php +++ b/var/PasswordHash.php @@ -33,7 +33,8 @@ * @link http://www.openwall.com/phpass/ * @since 2.5 */ -class PasswordHash { +class PasswordHash +{ var $itoa64; var $iteration_count_log2; var $portable_hashes; @@ -49,14 +50,49 @@ class PasswordHash { $this->portable_hashes = $portable_hashes; - $this->random_state = microtime() . uniqid(rand(), TRUE); // removed getmypid() for compability reasons + $this->random_state = microtime() . uniqid(rand(), true); // removed getmypid() for compability reasons + } + + function HashPassword($password) + { + $random = ''; + + if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) { + $random = $this->get_random_bytes(16); + $hash = + crypt($password, $this->gensalt_blowfish($random)); + if (strlen($hash) == 60) + return $hash; + } + + if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) { + if (strlen($random) < 3) + $random = $this->get_random_bytes(3); + $hash = + crypt($password, $this->gensalt_extended($random)); + if (strlen($hash) == 20) + return $hash; + } + + if (strlen($random) < 6) + $random = $this->get_random_bytes(6); + $hash = + $this->crypt_private($password, + $this->gensalt_private($random)); + if (strlen($hash) == 34) + return $hash; + +# Returning '*' on error is safe here, but would _not_ be safe +# in a crypt(3)-like function used _both_ for generating new +# hashes and for validating passwords against existing hashes. + return '*'; } function get_random_bytes($count) { $output = ''; - if ( @is_readable('/dev/urandom') && - ($fh = @fopen('/dev/urandom', 'rb'))) { + if (@is_readable('/dev/urandom') && + ($fh = @fopen('/dev/urandom', 'rb'))) { $output = fread($fh, $count); fclose($fh); } @@ -75,22 +111,81 @@ class PasswordHash { return $output; } + function gensalt_blowfish($input) + { +# This one needs to use a different order of characters and a +# different encoding scheme from the one in encode64() above. +# We care because the last character in our encoded string will +# only represent 2 bits. While two known implementations of +# bcrypt will happily accept and correct a salt string which +# has the 4 unused bits set to non-zero, we do not want to take +# chances and we also do not want to waste an additional byte +# of entropy. + $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + $output = '$2a$'; + $output .= chr(ord('0') + $this->iteration_count_log2 / 10); + $output .= chr(ord('0') + $this->iteration_count_log2 % 10); + $output .= '$'; + + $i = 0; + do { + $c1 = ord($input[$i ++]); + $output .= $itoa64[$c1 >> 2]; + $c1 = ($c1 & 0x03) << 4; + if ($i >= 16) { + $output .= $itoa64[$c1]; + break; + } + + $c2 = ord($input[$i ++]); + $c1 |= $c2 >> 4; + $output .= $itoa64[$c1]; + $c1 = ($c2 & 0x0f) << 2; + + $c2 = ord($input[$i ++]); + $c1 |= $c2 >> 6; + $output .= $itoa64[$c1]; + $output .= $itoa64[$c2 & 0x3f]; + } while (1); + + return $output; + } + + function gensalt_extended($input) + { + $count_log2 = min($this->iteration_count_log2 + 8, 24); +# This should be odd to not reveal weak DES keys, and the +# maximum valid value is (2**24 - 1) which is odd anyway. + $count = (1 << $count_log2) - 1; + + $output = '_'; + $output .= $this->itoa64[$count & 0x3f]; + $output .= $this->itoa64[($count >> 6) & 0x3f]; + $output .= $this->itoa64[($count >> 12) & 0x3f]; + $output .= $this->itoa64[($count >> 18) & 0x3f]; + + $output .= $this->encode64($input, 3); + + return $output; + } + function encode64($input, $count) { $output = ''; $i = 0; do { - $value = ord($input[$i++]); + $value = ord($input[$i ++]); $output .= $this->itoa64[$value & 0x3f]; if ($i < $count) $value |= ord($input[$i]) << 8; $output .= $this->itoa64[($value >> 6) & 0x3f]; - if ($i++ >= $count) + if ($i ++ >= $count) break; if ($i < $count) $value |= ord($input[$i]) << 16; $output .= $this->itoa64[($value >> 12) & 0x3f]; - if ($i++ >= $count) + if ($i ++ >= $count) break; $output .= $this->itoa64[($value >> 18) & 0x3f]; } while ($i < $count); @@ -98,16 +193,6 @@ class PasswordHash { return $output; } - function gensalt_private($input) - { - $output = '$P$'; - $output .= $this->itoa64[min($this->iteration_count_log2 + - ((PHP_VERSION >= '5') ? 5 : 3), 30)]; - $output .= $this->encode64($input, 6); - - return $output; - } - function crypt_private($password, $setting) { $output = '*0'; @@ -134,15 +219,15 @@ class PasswordHash { # consequently in lower iteration counts and hashes that are # quicker to crack (by non-PHP code). if (PHP_VERSION >= '5') { - $hash = md5($salt . $password, TRUE); + $hash = md5($salt . $password, true); do { - $hash = md5($hash . $password, TRUE); - } while (--$count); + $hash = md5($hash . $password, true); + } while (-- $count); } else { $hash = pack('H*', md5($salt . $password)); do { $hash = pack('H*', md5($hash . $password)); - } while (--$count); + } while (-- $count); } $output = substr($setting, 0, 12); @@ -151,100 +236,16 @@ class PasswordHash { return $output; } - function gensalt_extended($input) + function gensalt_private($input) { - $count_log2 = min($this->iteration_count_log2 + 8, 24); -# This should be odd to not reveal weak DES keys, and the -# maximum valid value is (2**24 - 1) which is odd anyway. - $count = (1 << $count_log2) - 1; - - $output = '_'; - $output .= $this->itoa64[$count & 0x3f]; - $output .= $this->itoa64[($count >> 6) & 0x3f]; - $output .= $this->itoa64[($count >> 12) & 0x3f]; - $output .= $this->itoa64[($count >> 18) & 0x3f]; - - $output .= $this->encode64($input, 3); + $output = '$P$'; + $output .= $this->itoa64[min($this->iteration_count_log2 + + ((PHP_VERSION >= '5') ? 5 : 3), 30)]; + $output .= $this->encode64($input, 6); return $output; } - function gensalt_blowfish($input) - { -# This one needs to use a different order of characters and a -# different encoding scheme from the one in encode64() above. -# We care because the last character in our encoded string will -# only represent 2 bits. While two known implementations of -# bcrypt will happily accept and correct a salt string which -# has the 4 unused bits set to non-zero, we do not want to take -# chances and we also do not want to waste an additional byte -# of entropy. - $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - - $output = '$2a$'; - $output .= chr(ord('0') + $this->iteration_count_log2 / 10); - $output .= chr(ord('0') + $this->iteration_count_log2 % 10); - $output .= '$'; - - $i = 0; - do { - $c1 = ord($input[$i++]); - $output .= $itoa64[$c1 >> 2]; - $c1 = ($c1 & 0x03) << 4; - if ($i >= 16) { - $output .= $itoa64[$c1]; - break; - } - - $c2 = ord($input[$i++]); - $c1 |= $c2 >> 4; - $output .= $itoa64[$c1]; - $c1 = ($c2 & 0x0f) << 2; - - $c2 = ord($input[$i++]); - $c1 |= $c2 >> 6; - $output .= $itoa64[$c1]; - $output .= $itoa64[$c2 & 0x3f]; - } while (1); - - return $output; - } - - function HashPassword($password) - { - $random = ''; - - if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) { - $random = $this->get_random_bytes(16); - $hash = - crypt($password, $this->gensalt_blowfish($random)); - if (strlen($hash) == 60) - return $hash; - } - - if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) { - if (strlen($random) < 3) - $random = $this->get_random_bytes(3); - $hash = - crypt($password, $this->gensalt_extended($random)); - if (strlen($hash) == 20) - return $hash; - } - - if (strlen($random) < 6) - $random = $this->get_random_bytes(6); - $hash = - $this->crypt_private($password, - $this->gensalt_private($random)); - if (strlen($hash) == 34) - return $hash; - -# Returning '*' on error is safe here, but would _not_ be safe -# in a crypt(3)-like function used _both_ for generating new -# hashes and for validating passwords against existing hashes. - return '*'; - } - function CheckPassword($password, $stored_hash) { $hash = $this->crypt_private($password, $stored_hash); diff --git a/var/Typecho/Common.php b/var/Typecho/Common.php index 770c2df3..de4054da 100644 --- a/var/Typecho/Common.php +++ b/var/Typecho/Common.php @@ -68,15 +68,6 @@ class Typecho_Common { /** 程序版本 */ const VERSION = '1.2/18.10.23'; - - /** - * 允许的属性 - * - * @access private - * @var array - */ - private static $_allowableAttributes = []; - /** * 默认编码 * @@ -84,7 +75,6 @@ class Typecho_Common * @var string */ public static $charset = 'UTF-8'; - /** * 异常处理类 * @@ -92,6 +82,13 @@ class Typecho_Common * @var string */ public static $exceptionHandle; + /** + * 允许的属性 + * + * @access private + * @var array + */ + private static $_allowableAttributes = []; /** * 将字符串变成大写的回调函数 @@ -186,14 +183,14 @@ class Typecho_Common { $attrs = trim($attrs); $len = strlen($attrs); - $pos = -1; + $pos = - 1; $result = []; $quote = ''; $key = ''; $value = ''; - for ($i = 0; $i < $len; $i++) { - if ('=' != $attrs[$i] && !ctype_space($attrs[$i]) && -1 == $pos) { + for ($i = 0; $i < $len; $i ++) { + if ('=' != $attrs[$i] && !ctype_space($attrs[$i]) && - 1 == $pos) { $key .= $attrs[$i]; /** 最后一个 */ @@ -205,30 +202,30 @@ class Typecho_Common } } - } else if (ctype_space($attrs[$i]) && -1 == $pos) { - $pos = -2; - } else if ('=' == $attrs[$i] && 0 > $pos) { + } elseif (ctype_space($attrs[$i]) && - 1 == $pos) { + $pos = - 2; + } elseif ('=' == $attrs[$i] && 0 > $pos) { $pos = 0; - } else if (('"' == $attrs[$i] || "'" == $attrs[$i]) && 0 == $pos) { + } elseif (('"' == $attrs[$i] || "'" == $attrs[$i]) && 0 == $pos) { $quote = $attrs[$i]; $value .= $attrs[$i]; $pos = 1; - } else if ($quote != $attrs[$i] && 1 == $pos) { + } elseif ($quote != $attrs[$i] && 1 == $pos) { $value .= $attrs[$i]; - } else if ($quote == $attrs[$i] && 1 == $pos) { - $pos = -1; + } elseif ($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) { + } elseif ('=' != $attrs[$i] && !ctype_space($attrs[$i]) && - 2 == $pos) { if ('' != ($key = trim($key))) { $result[$key] = ''; } $key = ''; $value = ''; - $pos = -1; + $pos = - 1; $key .= $attrs[$i]; } } @@ -257,6 +254,26 @@ class Typecho_Common } } + /** + * 将路径转化为链接 + * + * @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( + rtrim($prefix, '/') . '/' + . str_replace('//', '/', ltrim($path, '/')), + '/' + ); + } + /** * 程序初始化方法 * @@ -334,7 +351,7 @@ class Typecho_Common if ($exception instanceof Typecho_Db_Adapter_Exception) { $code = 503; $message = 'Error establishing a database connection'; - } else if ($exception instanceof Typecho_Db_Query_Exception) { + } elseif ($exception instanceof Typecho_Db_Query_Exception) { $message = 'Database Query Error'; } } else { @@ -493,26 +510,6 @@ EOF; 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数目来输出字符 * @@ -653,6 +650,55 @@ EOF; return str_replace('-', ' ', self::slugName($query)); } + /** + * 生成缩略名 + * + * @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 (__TYPECHO_MB_SUPPORTED__) { + 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; + } elseif ('UTF-8' == strtoupper(self::$charset)) { + if (preg_match_all("/[\w" . preg_quote('_-') . "]+/u", $str, $matches)) { + $str = implode('-', $matches[0]); + } + } else { + $str = str_replace(["'", ":", "\\", "/", '"'], "", $str); + $str = str_replace(["+", ",", ' ', ',', ' ', ".", "?", "=", "&", "!", "<", ">", "(", ")", "[", "]", "{", "}"], "-", $str); + } + + $str = trim($str, '-_'); + $str = !strlen($str) ? $default : $str; + return substr($str, 0, $maxLength); + } + /** * 将url中的非法字符串 * @@ -678,6 +724,26 @@ EOF; return self::buildUrl($params); } + /** + * 根据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); + } + /** * 处理XSS跨站攻击的过滤函数 * @@ -702,7 +768,7 @@ EOF; $search .= '1234567890!@#$%^&*()'; $search .= '~`";:?+/={}[]-_|\'\\'; - for ($i = 0; $i < strlen($search); $i++) { + 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 @@ -714,15 +780,17 @@ EOF; // now the only remaining whitespace attacks are \t, \n, and \r $ra1 = ['javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base']; - $ra2 = ['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']; + $ra2 = [ + '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++) { + for ($i = 0; $i < sizeof($ra); $i ++) { $pattern = '/'; - for ($j = 0; $j < strlen($ra[$i]); $j++) { + for ($j = 0; $j < strlen($ra[$i]); $j ++) { if ($j > 0) { $pattern .= '('; $pattern .= '(&#[xX]0{0,8}([9ab]);)'; @@ -841,77 +909,23 @@ EOF; } /** - * 生成缩略名 + * 判断hash值是否相等 * * @access public * - * @param string $str 需要生成缩略名的字符串 - * @param string $default 默认的缩略名 - * @param integer $maxLength 缩略名最大长度 + * @param string $from 源字符串 + * @param string $to 目标字符串 * - * @return string + * @return boolean */ - public static function slugName($str, $default = null, $maxLength = 128) + public static function hashValidate($from, $to) { - $str = trim($str); - - if (!strlen($str)) { - return $default; - } - - if (__TYPECHO_MB_SUPPORTED__) { - 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 if ('UTF-8' == strtoupper(self::$charset)) { - if (preg_match_all("/[\w" . preg_quote('_-') . "]+/u", $str, $matches)) { - $str = implode('-', $matches[0]); - } + if ('$T$' == substr($to, 0, 3)) { + $salt = substr($to, 3, 9); + return self::hash($from, $salt) === $to; } else { - $str = str_replace(["'", ":", "\\", "/", '"'], "", $str); - $str = str_replace(["+", ",", ' ', ',', ' ', ".", "?", "=", "&", "!", "<", ">", "(", ")", "[", "]", "{", "}"], "-", $str); + return md5($from) === $to; } - - $str = trim($str, '-_'); - $str = !strlen($str) ? $default : $str; - return substr($str, 0, $maxLength); - } - - /** - * 生成随机字符串 - * - * @access public - * - * @param integer $length 字符串长度 - * @param boolean $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; } /** @@ -943,30 +957,35 @@ EOF; $asc = ord($string[$pos]); $last = ($last * ord($salt[($last % $asc) % 9]) + $asc) % 95 + 32; $hash .= chr($last); - $pos++; + $pos ++; } return '$T$' . $salt . md5($hash); } /** - * 判断hash值是否相等 + * 生成随机字符串 * * @access public * - * @param string $from 源字符串 - * @param string $to 目标字符串 + * @param integer $length 字符串长度 + * @param boolean $specialChars 是否有特殊字符 * - * @return boolean + * @return string */ - public static function hashValidate($from, $to) + public static function randString($length, $specialChars = false) { - if ('$T$' == substr($to, 0, 3)) { - $salt = substr($to, 3, 9); - return self::hash($from, $salt) === $to; - } else { - return md5($from) === $to; + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + if ($specialChars) { + $chars .= '!@#$%^&*()'; } + + $result = ''; + $max = strlen($chars) - 1; + for ($i = 0; $i < $length; $i ++) { + $result .= $chars[rand(0, $max)]; + } + return $result; } /** @@ -995,7 +1014,7 @@ EOF; $now = time(); $from = $now - $timeout; - for ($i = $now; $i >= $from; $i--) { + for ($i = $now; $i >= $from; $i --) { if (sha1($secret . '&' . $i) == $token) { return true; } @@ -1004,26 +1023,6 @@ EOF; return false; } - /** - * 将路径转化为链接 - * - * @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( - rtrim($prefix, '/') . '/' - . str_replace('//', '/', ltrim($path, '/')), - '/' - ); - } - /** * 获取gravatar头像地址 * @@ -1315,319 +1314,319 @@ EOF; } $mimeTypes = [ - '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', - 'oga' => 'audio/ogg', - 'ogv' => 'video/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', + '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', + 'oga' => 'audio/ogg', + 'ogv' => 'video/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', - 'mp4' => 'video/mp4', - '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' + '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', + 'mp4' => 'video/mp4', + '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); diff --git a/var/Typecho/Db/Adapter.php b/var/Typecho/Db/Adapter.php index 6af4f8ec..33b6f286 100644 --- a/var/Typecho/Db/Adapter.php +++ b/var/Typecho/Db/Adapter.php @@ -32,8 +32,8 @@ interface Typecho_Db_Adapter public function connect(Typecho_Config $config); /** - * 获取数据库版本 - * + * 获取数据库版本 + * * @param mixed $handle * @return string */ @@ -58,7 +58,7 @@ interface Typecho_Db_Adapter * @param string $table 数据表 * @return resource */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL, $table = NULL); + public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null); /** * 将数据查询的其中一行作为数组取出,其中字段名对应数组键值 diff --git a/var/Typecho/Db/Adapter/Mysql.php b/var/Typecho/Db/Adapter/Mysql.php index 869c4aab..3bb27c63 100644 --- a/var/Typecho/Db/Adapter/Mysql.php +++ b/var/Typecho/Db/Adapter/Mysql.php @@ -38,13 +38,13 @@ class Typecho_Db_Adapter_Mysql implements Typecho_Db_Adapter * 数据库连接函数 * * @param Typecho_Config $config 数据库配置 - * @throws Typecho_Db_Exception * @return mixed + * @throws Typecho_Db_Exception */ public function connect(Typecho_Config $config) { if ($this->_dbLink = @mysql_connect($config->host . (empty($config->port) ? '' : ':' . $config->port), - $config->user, $config->password, true)) { + $config->user, $config->password, true)) { if (@mysql_select_db($config->database, $this->_dbLink)) { if ($config->charset) { mysql_query("SET NAMES '{$config->charset}'", $this->_dbLink); @@ -58,8 +58,8 @@ class Typecho_Db_Adapter_Mysql implements Typecho_Db_Adapter } /** - * 获取数据库版本 - * + * 获取数据库版本 + * * @param mixed $handle * @return string */ @@ -89,10 +89,10 @@ class Typecho_Db_Adapter_Mysql implements Typecho_Db_Adapter * @param integer $op 数据库读写状态 * @param string $action 数据库动作 * @param string $table 数据表 - * @throws Typecho_Db_Exception * @return resource + * @throws Typecho_Db_Exception */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL, $table = NULL) + public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null) { if ($resource = @mysql_query($query, $handle)) { return $resource; @@ -102,6 +102,18 @@ class Typecho_Db_Adapter_Mysql implements Typecho_Db_Adapter throw new Typecho_Db_Query_Exception(@mysql_error($this->_dbLink), mysql_errno($this->_dbLink)); } + /** + * 对象引号过滤 + * + * @access public + * @param string $string + * @return string + */ + public function quoteColumn($string) + { + return '`' . $string . '`'; + } + /** * 将数据查询的其中一行作为数组取出,其中字段名对应数组键值 * @@ -132,19 +144,7 @@ class Typecho_Db_Adapter_Mysql implements Typecho_Db_Adapter */ public function quoteValue($string) { - return '\'' . str_replace(array('\'', '\\'), array('\'\'', '\\\\'), $string) . '\''; - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return '`' . $string . '`'; + return '\'' . str_replace(['\'', '\\'], ['\'\'', '\\\\'], $string) . '\''; } /** @@ -158,16 +158,16 @@ class Typecho_Db_Adapter_Mysql implements Typecho_Db_Adapter { if (!empty($sql['join'])) { foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; + [$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']; + $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['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; + $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; } /** diff --git a/var/Typecho/Db/Adapter/Mysqli.php b/var/Typecho/Db/Adapter/Mysqli.php index 4c437f20..b5303880 100644 --- a/var/Typecho/Db/Adapter/Mysqli.php +++ b/var/Typecho/Db/Adapter/Mysqli.php @@ -38,8 +38,8 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter * 数据库连接函数 * * @param Typecho_Config $config 数据库配置 - * @throws Typecho_Db_Exception * @return mixed + * @throws Typecho_Db_Exception */ public function connect(Typecho_Config $config) { @@ -62,8 +62,8 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter } /** - * 获取数据库版本 - * + * 获取数据库版本 + * * @param mixed $handle * @return string */ @@ -93,10 +93,10 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter * @param integer $op 数据库读写状态 * @param string $action 数据库动作 * @param string $table 数据表 - * @throws Typecho_Db_Exception * @return resource + * @throws Typecho_Db_Exception */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL, $table = NULL) + public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null) { if ($resource = @$this->_dbLink->query($query)) { return $resource; @@ -106,6 +106,18 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter throw new Typecho_Db_Query_Exception($this->_dbLink->error, $this->_dbLink->errno); } + /** + * 对象引号过滤 + * + * @access public + * @param string $string + * @return string + */ + public function quoteColumn($string) + { + return $this->_dbLink->real_escape_string($string); + } + /** * 将数据查询的其中一行作为数组取出,其中字段名对应数组键值 * @@ -136,19 +148,7 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter */ public function quoteValue($string) { - return '\'' . str_replace(array('\'', '\\'), array('\'\'', '\\\\'), $string) . '\''; - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return $this->_dbLink->real_escape_string($string); + return '\'' . str_replace(['\'', '\\'], ['\'\'', '\\\\'], $string) . '\''; } /** @@ -162,16 +162,16 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter { if (!empty($sql['join'])) { foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; + [$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']; + $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['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; + $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; } /** diff --git a/var/Typecho/Db/Adapter/Pdo.php b/var/Typecho/Db/Adapter/Pdo.php index 9a166c2e..c06f2d3a 100644 --- a/var/Typecho/Db/Adapter/Pdo.php +++ b/var/Typecho/Db/Adapter/Pdo.php @@ -46,8 +46,8 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter * 数据库连接函数 * * @param Typecho_Config $config 数据库配置 - * @throws Typecho_Db_Exception * @return PDO + * @throws Typecho_Db_Exception */ public function connect(Typecho_Config $config) { @@ -61,18 +61,6 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter } } - /** - * 获取数据库版本 - * - * @param mixed $handle - * @return string - */ - public function getVersion($handle) - { - return 'pdo:' . $handle->getAttribute(PDO::ATTR_DRIVER_NAME) - . ' ' . $handle->getAttribute(PDO::ATTR_SERVER_VERSION); - } - /** * 初始化数据库 * @@ -83,6 +71,18 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter */ abstract public function init(Typecho_Config $config); + /** + * 获取数据库版本 + * + * @param mixed $handle + * @return string + */ + public function getVersion($handle) + { + return 'pdo:' . $handle->getAttribute(PDO::ATTR_DRIVER_NAME) + . ' ' . $handle->getAttribute(PDO::ATTR_SERVER_VERSION); + } + /** * 执行数据库查询 * @@ -91,10 +91,10 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter * @param integer $op 数据库读写状态 * @param string $action 数据库动作 * @param string $table 数据表 - * @throws Typecho_Db_Exception * @return resource + * @throws Typecho_Db_Exception */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL, $table = NULL) + public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null) { try { $this->_lastTable = $table; @@ -141,24 +141,6 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter 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){} - /** * 取出最后一次查询影响的行数 * diff --git a/var/Typecho/Db/Adapter/Pdo/Mysql.php b/var/Typecho/Db/Adapter/Pdo/Mysql.php index c1d277a3..63893e3f 100644 --- a/var/Typecho/Db/Adapter/Pdo/Mysql.php +++ b/var/Typecho/Db/Adapter/Pdo/Mysql.php @@ -39,6 +39,18 @@ class Typecho_Db_Adapter_Pdo_Mysql extends Typecho_Db_Adapter_Pdo $this->query('TRUNCATE TABLE ' . $this->quoteColumn($table), $handle); } + /** + * 对象引号过滤 + * + * @access public + * @param string $string + * @return string + */ + public function quoteColumn($string) + { + return '`' . $string . '`'; + } + /** * 初始化数据库 * @@ -55,18 +67,6 @@ class Typecho_Db_Adapter_Pdo_Mysql extends Typecho_Db_Adapter_Pdo return $pdo; } - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return '`' . $string . '`'; - } - /** * 引号转义函数 * @@ -75,7 +75,7 @@ class Typecho_Db_Adapter_Pdo_Mysql extends Typecho_Db_Adapter_Pdo */ public function quoteValue($string) { - return '\'' . str_replace(array('\'', '\\'), array('\'\'', '\\\\'), $string) . '\''; + return '\'' . str_replace(['\'', '\\'], ['\'\'', '\\\\'], $string) . '\''; } /** @@ -89,15 +89,15 @@ class Typecho_Db_Adapter_Pdo_Mysql extends Typecho_Db_Adapter_Pdo { if (!empty($sql['join'])) { foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; + [$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']; + $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['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; + $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; } } diff --git a/var/Typecho/Db/Adapter/Pdo/Pgsql.php b/var/Typecho/Db/Adapter/Pdo/Pgsql.php index a7865903..b2c6e229 100644 --- a/var/Typecho/Db/Adapter/Pdo/Pgsql.php +++ b/var/Typecho/Db/Adapter/Pdo/Pgsql.php @@ -20,7 +20,7 @@ class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo * * @var array */ - private $_pk = array(); + private $_pk = []; /** * 兼容的插入模式 @@ -53,20 +53,6 @@ class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo $this->query('TRUNCATE TABLE ' . $this->quoteColumn($table) . ' RESTART IDENTITY', $handle); } - /** - * 初始化数据库 - * - * @param Typecho_Config $config 数据库配置 - * @access public - * @return PDO - */ - public function init(Typecho_Config $config) - { - $pdo = new PDO("pgsql:dbname={$config->database};host={$config->host};port={$config->port}", $config->user, $config->password); - $pdo->exec("SET NAMES '{$config->charset}'"); - return $pdo; - } - /** * 覆盖标准动作 * fix #710 @@ -79,7 +65,7 @@ class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo * @return resource * @throws Typecho_Db_Exception */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL, $table = NULL) + public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null) { if (Typecho_Db::INSERT == $action && !empty($table)) { if (!isset($this->_pk[$table])) { @@ -111,7 +97,6 @@ WHERE return parent::query($query, $handle, $op, $action, $table); // TODO: Change the autogenerated stub } - /** * 对象引号过滤 * @@ -124,6 +109,20 @@ WHERE return '"' . $string . '"'; } + /** + * 初始化数据库 + * + * @param Typecho_Config $config 数据库配置 + * @access public + * @return PDO + */ + public function init(Typecho_Config $config) + { + $pdo = new PDO("pgsql:dbname={$config->database};host={$config->host};port={$config->port}", $config->user, $config->password); + $pdo->exec("SET NAMES '{$config->charset}'"); + return $pdo; + } + /** * 合成查询语句 * @@ -135,16 +134,16 @@ WHERE { if (!empty($sql['join'])) { foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; + [$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']; + $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['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; + $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; } /** @@ -159,7 +158,7 @@ WHERE if ($this->_compatibleInsert) { $this->_compatibleInsert = false; return $resource->fetchColumn(0); - } else if ($handle->query('SELECT oid FROM pg_class WHERE relname = ' . $this->quoteValue($this->_lastTable . '_seq'))->fetchAll()) { + } elseif ($handle->query('SELECT oid FROM pg_class WHERE relname = ' . $this->quoteValue($this->_lastTable . '_seq'))->fetchAll()) { /** 查看是否存在序列,可能需要更严格的检查 */ return $handle->lastInsertId($this->_lastTable . '_seq'); } diff --git a/var/Typecho/Db/Adapter/Pdo/SQLite.php b/var/Typecho/Db/Adapter/Pdo/SQLite.php index 58fa7714..ab91959d 100644 --- a/var/Typecho/Db/Adapter/Pdo/SQLite.php +++ b/var/Typecho/Db/Adapter/Pdo/SQLite.php @@ -44,6 +44,18 @@ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo $this->query('DELETE FROM ' . $this->quoteColumn($table), $handle); } + /** + * 对象引号过滤 + * + * @access public + * @param string $string + * @return string + */ + public function quoteColumn($string) + { + return '"' . $string . '"'; + } + /** * 初始化数据库 * @@ -58,6 +70,15 @@ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo return $pdo; } + /** + * @param resource $resource + * @return object + */ + public function fetchObject($resource) + { + return (object)$this->fetch($resource); + } + /** * @param resource $resource * @return array @@ -67,27 +88,6 @@ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo return Typecho_Common::filterSQLite2ColumnName(parent::fetch($resource)); } - /** - * @param resource $resource - * @return object - */ - public function fetchObject($resource) - { - return (object) $this->fetch($resource); - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return '"' . $string . '"'; - } - /** * 合成查询语句 * @@ -99,16 +99,16 @@ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo { if (!empty($sql['join'])) { foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; + [$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']; + $sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit']; + $sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset']; $query = 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . - $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; + $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; if ($this->_isSQLite2) { $query = Typecho_Common::filterSQLite2CountQuery($query); diff --git a/var/Typecho/Db/Adapter/Pgsql.php b/var/Typecho/Db/Adapter/Pgsql.php index ea1a9424..56db2d0e 100644 --- a/var/Typecho/Db/Adapter/Pgsql.php +++ b/var/Typecho/Db/Adapter/Pgsql.php @@ -15,14 +15,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter { - /** - * 数据库连接字符串标示 - * - * @access private - * @var resource - */ - private $_dbLink; - /** * 最后一次操作的数据表 * @@ -30,6 +22,13 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter * @var string */ protected $_lastTable; + /** + * 数据库连接字符串标示 + * + * @access private + * @var resource + */ + private $_dbLink; /** * 判断适配器是否可用 @@ -46,8 +45,8 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter * 数据库连接函数 * * @param Typecho_Config $config 数据库配置 - * @throws Typecho_Db_Exception * @return resource + * @throws Typecho_Db_Exception */ public function connect(Typecho_Config $config) { @@ -63,8 +62,8 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter } /** - * 获取数据库版本 - * + * 获取数据库版本 + * * @param mixed $handle * @return string */ @@ -95,10 +94,10 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter * @param integer $op 数据库读写状态 * @param string $action 数据库动作 * @param string $table 数据表 - * @throws Typecho_Db_Exception * @return resource + * @throws Typecho_Db_Exception */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL, $table = NULL) + public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null) { $this->_lastTable = $table; if ($resource = @pg_query($handle, $query)) { @@ -107,7 +106,19 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter /** 数据库异常 */ throw new Typecho_Db_Query_Exception(@pg_last_error($this->_dbLink), - pg_result_error_field(pg_get_result($this->_dbLink), PGSQL_DIAG_SQLSTATE)); + pg_result_error_field(pg_get_result($this->_dbLink), PGSQL_DIAG_SQLSTATE)); + } + + /** + * 对象引号过滤 + * + * @access public + * @param string $string + * @return string + */ + public function quoteColumn($string) + { + return '"' . $string . '"'; } /** @@ -132,29 +143,6 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter 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 . '"'; - } - /** * 合成查询语句 * @@ -166,16 +154,16 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter { if (!empty($sql['join'])) { foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; + [$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']; + $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['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; + $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; } /** @@ -206,4 +194,15 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter return 0; } + + /** + * 引号转义函数 + * + * @param string $string 需要转义的字符串 + * @return string + */ + public function quoteValue($string) + { + return '\'' . pg_escape_string($string) . '\''; + } } diff --git a/var/Typecho/Db/Adapter/SQLite.php b/var/Typecho/Db/Adapter/SQLite.php index a625b9d7..6cb1b59e 100644 --- a/var/Typecho/Db/Adapter/SQLite.php +++ b/var/Typecho/Db/Adapter/SQLite.php @@ -38,8 +38,8 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter * 数据库连接函数 * * @param Typecho_Config $config 数据库配置 - * @throws Typecho_Db_Exception * @return resource + * @throws Typecho_Db_Exception */ public function connect(Typecho_Config $config) { @@ -52,8 +52,8 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter } /** - * 获取数据库版本 - * + * 获取数据库版本 + * * @param mixed $handle * @return string */ @@ -86,7 +86,7 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter * @return resource|SQLiteResult * @throws Typecho_Db_Query_Exception */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL, $table = NULL) + public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null) { if ($resource = @sqlite_query($query, $handle)) { return $resource; @@ -97,39 +97,6 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter throw new Typecho_Db_Query_Exception(sqlite_error_string($errorCode), $errorCode); } - /** - * 将数据查询的其中一行作为数组取出,其中字段名对应数组键值 - * - * @param resource $resource 查询返回资源标识 - * @return array - */ - public function fetch($resource) - { - return Typecho_Common::filterSQLite2ColumnName(sqlite_fetch_array($resource, SQLITE_ASSOC)); - } - - /** - * 将数据查询的其中一行作为对象取出,其中字段名对应对象属性 - * - * @param resource $resource 查询的资源数据 - * @return object - */ - public function fetchObject($resource) - { - return (object) $this->fetch($resource); - } - - /** - * 引号转义函数 - * - * @param string $string 需要转义的字符串 - * @return string - */ - public function quoteValue($string) - { - return '\'' . str_replace('\'', '\'\'', $string) . '\''; - } - /** * 对象引号过滤 * @@ -142,6 +109,39 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter return '"' . $string . '"'; } + /** + * 将数据查询的其中一行作为对象取出,其中字段名对应对象属性 + * + * @param resource $resource 查询的资源数据 + * @return object + */ + public function fetchObject($resource) + { + return (object)$this->fetch($resource); + } + + /** + * 将数据查询的其中一行作为数组取出,其中字段名对应数组键值 + * + * @param resource $resource 查询返回资源标识 + * @return array + */ + public function fetch($resource) + { + return Typecho_Common::filterSQLite2ColumnName(sqlite_fetch_array($resource, SQLITE_ASSOC)); + } + + /** + * 引号转义函数 + * + * @param string $string 需要转义的字符串 + * @return string + */ + public function quoteValue($string) + { + return '\'' . str_replace('\'', '\'\'', $string) . '\''; + } + /** * 合成查询语句 * @@ -153,16 +153,16 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter { if (!empty($sql['join'])) { foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; + [$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']; + $sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit']; + $sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset']; return Typecho_Common::filterSQLite2CountQuery('SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . - $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']); + $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']); } /** diff --git a/var/Typecho/Db/Query.php b/var/Typecho/Db/Query.php index 0dc4b4d6..34e81be0 100644 --- a/var/Typecho/Db/Query.php +++ b/var/Typecho/Db/Query.php @@ -10,7 +10,7 @@ /** * Typecho数据库查询语句构建类 * 使用方法: - * $query = new Typecho_Db_Query(); //或者使用DB积累的sql方法返回实例化对象 + * $query = new Typecho_Db_Query(); //或者使用DB积累的sql方法返回实例化对象 * $query->select('posts', 'post_id, post_title') * ->where('post_id = %d', 1) * ->limit(1); @@ -27,24 +27,24 @@ class Typecho_Db_Query const KEYWORDS = '*PRIMARY|AND|OR|LIKE|BINARY|BY|DISTINCT|AS|IN|IS|NULL'; /** - * 默认字段 - * + * 默认字段 + * * @var array * @access private */ - private static $_default = array( - 'action' => NULL, - 'table' => NULL, + private static $_default = [ + 'action' => null, + 'table' => null, 'fields' => '*', - 'join' => array(), - 'where' => NULL, - 'limit' => NULL, - 'offset' => NULL, - 'order' => NULL, - 'group' => NULL, - 'having' => NULL, - 'rows' => array(), - ); + 'join' => [], + 'where' => null, + 'limit' => null, + 'offset' => null, + 'order' => null, + 'group' => null, + 'having' => null, + 'rows' => [], + ]; /** * 数据库适配器 @@ -71,7 +71,7 @@ class Typecho_Db_Query /** * @var array */ - private $_params = array(); + private $_params = []; /** * 构造函数,引用数据库适配器作为内部数据 @@ -87,6 +87,67 @@ class Typecho_Db_Query $this->_sqlPreBuild = self::$_default; } + /** + * set default params + * + * @param array $default + */ + public static function setDefault(array $default) + { + self::$_default = array_merge(self::$_default, $default); + } + + /** + * 获取参数 + * + * @return array + */ + public function getParams() + { + return $this->_params; + } + + /** + * 获取查询字串属性值 + * + * @access public + * @param string $attributeName 属性名称 + * @return string + */ + public function getAttribute($attributeName) + { + return $this->_sqlPreBuild[$attributeName] ?? null; + } + + /** + * 清除查询字串属性值 + * + * @access public + * @param string $attributeName 属性名称 + * @return Typecho_Db_Query + */ + public function cleanAttribute($attributeName) + { + if (isset($this->_sqlPreBuild[$attributeName])) { + $this->_sqlPreBuild[$attributeName] = self::$_default[$attributeName]; + } + return $this; + } + + /** + * 连接表 + * + * @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'][] = [$this->filterPrefix($table), $this->filterColumn($condition), $op]; + return $this; + } + /** * 过滤表前缀,表前缀由table.构成 * @@ -121,9 +182,9 @@ class Typecho_Db_Query if (ctype_alnum($cha) || false !== strpos('_*', $cha)) { if (!$lastIsAlnum) { if ($quotes > 0 && !ctype_digit($word) && '.' != $split - && false === strpos(self::KEYWORDS, strtoupper($word))) { + && false === strpos(self::KEYWORDS, strtoupper($word))) { $word = $this->_adapter->quoteColumn($word); - } else if ('.' == $split && 'table' == $word) { + } elseif ('.' == $split && 'table' == $word) { $word = $this->_prefix; $split = ''; } @@ -142,8 +203,8 @@ class Typecho_Db_Query if (0 == $quotes) { if (false !== strpos(' ,)=<>.+-*/', $cha)) { $quotes = 1; - } else if ('(' == $cha) { - $quotes = -1; + } elseif ('(' == $cha) { + $quotes = - 1; } } @@ -160,33 +221,31 @@ class Typecho_Db_Query } /** - * 从参数中合成查询字段 + * AND条件查询语句 * - * @access private - * @param array $parameters - * @return string + * @param ...$args + * @return $this */ - private function getColumnFromParameters(array $parameters) + public function where(...$args) { - $fields = array(); + [$condition] = $args; + $condition = str_replace('?', "%s", $this->filterColumn($condition)); + $operator = empty($this->_sqlPreBuild['where']) ? ' WHERE ' : ' AND'; - foreach ($parameters as $value) { - if (is_array($value)) { - foreach ($value as $key => $val) { - $fields[] = $key . ' AS ' . $val; - } - } else { - $fields[] = $value; - } + if (count($args) <= 1) { + $this->_sqlPreBuild['where'] .= $operator . ' (' . $condition . ')'; + } else { + array_shift($args); + $this->_sqlPreBuild['where'] .= $operator . ' (' . vsprintf($condition, $this->quoteValues($args)) . ')'; } - return $this->filterColumn(implode(' , ', $fields)); + return $this; } /** - * 转义参数 - * - * @param array $values + * 转义参数 + * + * @param array $values * @access protected * @return array */ @@ -194,7 +253,7 @@ class Typecho_Db_Query { foreach ($values as &$value) { if (is_array($value)) { - $value = '(' . implode(',', array_map(array($this, 'quoteValue'), $value)) . ')'; + $value = '(' . implode(',', array_map([$this, 'quoteValue'], $value)) . ')'; } else { $value = $this->quoteValue($value); } @@ -215,91 +274,6 @@ class Typecho_Db_Query return '#param:' . (count($this->_params) - 1) . '#'; } - /** - * 获取参数 - * - * @return array - */ - public function getParams() - { - return $this->_params; - } - - /** - * set default params - * - * @param array $default - */ - public static function setDefault(array $default) - { - self::$_default = array_merge(self::$_default, $default); - } - - /** - * 获取查询字串属性值 - * - * @access public - * @param string $attributeName 属性名称 - * @return string - */ - public function getAttribute($attributeName) - { - return isset($this->_sqlPreBuild[$attributeName]) ? $this->_sqlPreBuild[$attributeName] : NULL; - } - - /** - * 清除查询字串属性值 - * - * @access public - * @param string $attributeName 属性名称 - * @return Typecho_Db_Query - */ - public function cleanAttribute($attributeName) - { - if (isset($this->_sqlPreBuild[$attributeName])) { - $this->_sqlPreBuild[$attributeName] = self::$_default[$attributeName]; - } - return $this; - } - - /** - * 连接表 - * - * @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, $this->quoteValues($args)) . ')'; - } - - return $this; - } - /** * OR条件查询语句 * @@ -407,7 +381,7 @@ class Typecho_Db_Query $this->_sqlPreBuild['order'] .= ', '; } - $this->_sqlPreBuild['order'] .= $this->filterColumn($orderby) . (empty($sort) ? NULL : ' ' . $sort); + $this->_sqlPreBuild['order'] .= $this->filterColumn($orderby) . (empty($sort) ? null : ' ' . $sort); return $this; } @@ -461,6 +435,30 @@ class Typecho_Db_Query return $this; } + /** + * 从参数中合成查询字段 + * + * @access private + * @param array $parameters + * @return string + */ + private function getColumnFromParameters(array $parameters) + { + $fields = []; + + 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)); + } + /** * 查询记录操作(SELECT) * @@ -542,17 +540,17 @@ class Typecho_Db_Query 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']; + . $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']; + . $this->_sqlPreBuild['table'] + . $this->_sqlPreBuild['where']; case Typecho_Db::UPDATE: - $columns = array(); + $columns = []; if (isset($this->_sqlPreBuild['rows'])) { foreach ($this->_sqlPreBuild['rows'] as $key => $val) { $columns[] = "$key = $val"; @@ -560,11 +558,11 @@ class Typecho_Db_Query } return 'UPDATE ' - . $this->_sqlPreBuild['table'] - . ' SET ' . implode(' , ', $columns) - . $this->_sqlPreBuild['where']; + . $this->_sqlPreBuild['table'] + . ' SET ' . implode(' , ', $columns) + . $this->_sqlPreBuild['where']; default: - return NULL; + return null; } } } diff --git a/var/Typecho/Http/Client.php b/var/Typecho/Http/Client.php index 4d4a7cf9..d4760d15 100644 --- a/var/Typecho/Http/Client.php +++ b/var/Typecho/Http/Client.php @@ -32,27 +32,27 @@ class Typecho_Http_Client * 获取可用的连接 * * @access public - * @return Typecho_Http_Client_Adapter + * @return ?Typecho_Http_Client_Adapter */ - public static function get() + public static function get(): ?Typecho_Http_Client { $adapters = func_get_args(); if (empty($adapters)) { - $adapters = array(); + $adapters = []; $adapterFiles = glob(dirname(__FILE__) . '/Client/Adapter/*.php'); foreach ($adapterFiles as $file) { - $adapters[] = substr(basename($file), 0, -4); + $adapters[] = substr(basename($file), 0, - 4); } } foreach ($adapters as $adapter) { $adapterName = 'Typecho_Http_Client_Adapter_' . $adapter; - if (Typecho_Common::isAvailableClass($adapterName) && call_user_func(array($adapterName, 'isAvailable'))) { + if (Typecho_Common::isAvailableClass($adapterName) && call_user_func([$adapterName, 'isAvailable'])) { return new $adapterName(); } } - return false; + return null; } } diff --git a/var/Typecho/Http/Client/Adapter.php b/var/Typecho/Http/Client/Adapter.php index f9dccd45..cea19a53 100644 --- a/var/Typecho/Http/Client/Adapter.php +++ b/var/Typecho/Http/Client/Adapter.php @@ -49,7 +49,7 @@ abstract class Typecho_Http_Client_Adapter * @access protected * @var array */ - protected $data = array(); + protected $data = []; /** * 文件列表 @@ -57,7 +57,7 @@ abstract class Typecho_Http_Client_Adapter * @access protected * @var array */ - protected $files = array(); + protected $files = []; /** * 头信息参数 @@ -65,7 +65,7 @@ abstract class Typecho_Http_Client_Adapter * @access protected * @var array */ - protected $headers = array(); + protected $headers = []; /** * cookies @@ -73,7 +73,7 @@ abstract class Typecho_Http_Client_Adapter * @access protected * @var array */ - protected $cookies = array(); + protected $cookies = []; /** * 协议名称及版本 @@ -137,7 +137,7 @@ abstract class Typecho_Http_Client_Adapter * @access protected * @var array */ - protected $responseHeader = array(); + protected $responseHeader = []; /** * 回执代码 @@ -166,19 +166,6 @@ abstract class Typecho_Http_Client_Adapter return true; } - /** - * 设置方法名 - * - * @access public - * @param string $method - * @return Typecho_Http_Client_Adapter - */ - public function setMethod($method) - { - $this->method = $method; - return $this; - } - /** * 设置指定的COOKIE值 * @@ -221,6 +208,19 @@ abstract class Typecho_Http_Client_Adapter return $this; } + /** + * 设置方法名 + * + * @access public + * @param string $method + * @return Typecho_Http_Client_Adapter + */ + public function setMethod($method) + { + $this->method = $method; + return $this; + } + /** * 设置需要POST的文件 * @@ -274,21 +274,6 @@ abstract class Typecho_Http_Client_Adapter 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; - } - /** * 发送请求 * @@ -307,7 +292,7 @@ abstract class Typecho_Http_Client_Adapter throw new Typecho_Http_Client_Exception('Unknown Host', 500); } - if (!in_array($params['scheme'], array('http', 'https'))) { + if (!in_array($params['scheme'], ['http', 'https'])) { throw new Typecho_Http_Client_Exception('Unknown Scheme', 500); } @@ -350,7 +335,7 @@ abstract class Typecho_Http_Client_Adapter $foundStatus = false; $foundInfo = false; - $lines = array(); + $lines = []; foreach ($rows as $key => $line) { if (!$foundStatus) { @@ -383,6 +368,30 @@ abstract class Typecho_Http_Client_Adapter return $this->responseBody; } + /** + * 设置头信息参数 + * + * @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 请求地址 + * @return string + */ + abstract protected function httpSend($url); + /** * 获取回执的头部信息 * @@ -393,7 +402,7 @@ abstract class Typecho_Http_Client_Adapter public function getResponseHeader($key) { $key = strtolower($key); - return isset($this->responseHeader[$key]) ? $this->responseHeader[$key] : NULL; + return $this->responseHeader[$key] ?? null; } /** @@ -417,13 +426,4 @@ abstract class Typecho_Http_Client_Adapter { return $this->responseBody; } - - /** - * 需要实现的请求方法 - * - * @access public - * @param string $url 请求地址 - * @return string - */ - abstract protected function httpSend($url); } diff --git a/var/Typecho/Http/Client/Adapter/Curl.php b/var/Typecho/Http/Client/Adapter/Curl.php index bf08fa14..587aa9dc 100644 --- a/var/Typecho/Http/Client/Adapter/Curl.php +++ b/var/Typecho/Http/Client/Adapter/Curl.php @@ -78,7 +78,7 @@ class Typecho_Http_Client_Adapter_Curl extends Typecho_Http_Client_Adapter unset($this->headers['User-Agent']); } - $headers = array(); + $headers = []; if (isset($this->headers['Rfc'])) { $headers[] = $this->headers['Rfc']; diff --git a/var/Typecho/Http/Client/Adapter/Socket.php b/var/Typecho/Http/Client/Adapter/Socket.php index c36ff5ee..32f43998 100644 --- a/var/Typecho/Http/Client/Adapter/Socket.php +++ b/var/Typecho/Http/Client/Adapter/Socket.php @@ -31,6 +31,24 @@ class Typecho_Http_Client_Adapter_Socket extends Typecho_Http_Client_Adapter return function_exists("fsockopen"); } + /** + * 获取回执身体 + * + * @access public + * @return string + */ + public function getResponseBody() + { + /** 支持chunked编码 */ + if ('chunked' == $this->getResponseHeader('Transfer-Encoding')) { + $parts = explode("\r\n", $this->responseBody, 2); + $counter = hexdec($parts[0]); + $this->responseBody = substr($parts[1], 0, $counter); + } + + return $this->responseBody; + } + /** * 发送请求 * @@ -119,7 +137,7 @@ class Typecho_Http_Client_Adapter_Socket extends Typecho_Http_Client_Adapter } else { throw new Typecho_Http_Client_Exception(__CLASS__ . ': could not read from ' . $this->host . ':' . $this->port, 500); } - } else if (strlen($buf) < 4096) { + } elseif (strlen($buf) < 4096) { $info = stream_get_meta_data($socket); if ($info['timed_out']) { @@ -133,22 +151,4 @@ class Typecho_Http_Client_Adapter_Socket extends Typecho_Http_Client_Adapter fclose($socket); return $response; } - - /** - * 获取回执身体 - * - * @access public - * @return string - */ - public function getResponseBody() - { - /** 支持chunked编码 */ - if ('chunked' == $this->getResponseHeader('Transfer-Encoding')) { - $parts = explode("\r\n", $this->responseBody, 2); - $counter = hexdec($parts[0]); - $this->responseBody = substr($parts[1], 0, $counter); - } - - return $this->responseBody; - } } diff --git a/var/Typecho/I18n/GetText.php b/var/Typecho/I18n/GetText.php index 518823ff..e084abcd 100644 --- a/var/Typecho/I18n/GetText.php +++ b/var/Typecho/I18n/GetText.php @@ -35,6 +35,7 @@ */ //reload by 70 (typecho group) + /** * This file is part of PHP-gettext * @@ -49,16 +50,16 @@ class Typecho_I18n_GetText //private: private $BYTEORDER = 0; // 0: low endian, 1: big endian - private $STREAM = NULL; + 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 $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 + 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 */ @@ -79,13 +80,13 @@ class Typecho_I18n_GetText // Caching can be turned off $this->enable_cache = $enable_cache; $this->STREAM = @fopen($file, 'rb'); - + $unpacked = unpack('c', $this->read(4)); $magic = array_shift($unpacked); - if (-34 == $magic) { + if (- 34 == $magic) { $this->BYTEORDER = 0; - } elseif (-107 == $magic) { + } elseif (- 107 == $magic) { $this->BYTEORDER = 1; } else { $this->error = 1; // not MO file @@ -101,9 +102,9 @@ class Typecho_I18n_GetText } /** - * read - * - * @param mixed $count + * read + * + * @param mixed $count * @access private * @return void */ @@ -115,7 +116,7 @@ class Typecho_I18n_GetText return fread($this->STREAM, $count); } - return NULL; + return null; } /** @@ -130,130 +131,6 @@ class Typecho_I18n_GetText 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, $this->read(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 ('' => NULL); - /* 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 * @@ -277,7 +154,7 @@ class Typecho_I18n_GetText } else { // Caching not enabled, try to find string $num = $this->find_string($string); - if ($num == -1) + if ($num == - 1) return $string; else return $this->get_translation_string($num); @@ -285,53 +162,127 @@ class Typecho_I18n_GetText } /** - * Get possible plural forms from MO header + * 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 - * @return string plural form header */ - private function get_plural_forms() + private function load_tables() { - // lets assume message number 0 is header - // this is true, right? - $this->load_tables(); + if (is_array($this->cache_translations) && + is_array($this->table_originals) && + is_array($this->table_translations)) + return; - // 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); + /* 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 = ['' => null]; + /* 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; + } } - if (preg_match("/plural\-forms: ([^\n]*)\n/i", $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 + * 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, $this->read(4 * $count)); + } + + /** + * Binary search for string * * @access private - * @param n count - * @return int array index of the right plural form + * @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 select_string($n) + private function find_string($string, $start = - 1, $end = - 1) { - $string = $this->get_plural_forms(); - $string = str_replace('nplurals',"\$total",$string); - $string = str_replace("n",$n,$string); - $string = str_replace('plural',"\$plural",$string); + 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; + } elseif ($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; + elseif ($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); + } + } - $total = 0; - $plural = 0; + /** + * 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; + } - eval("$string"); - if ($plural >= $total) $plural = $total - 1; - return $plural; + /** + * 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; } /** @@ -359,11 +310,11 @@ class Typecho_I18n_GetText $select = $this->select_string($number); // this should contains all strings separated by NULLs - $key = $single.chr(0).$plural; + $key = $single . chr(0) . $plural; if ($this->enable_cache) { - if (! array_key_exists($key, $this->cache_translations)) { + if (!array_key_exists($key, $this->cache_translations)) { return ($number != 1) ? $plural : $single; } else { $result = $this->cache_translations[$key]; @@ -372,7 +323,7 @@ class Typecho_I18n_GetText } } else { $num = $this->find_string($key); - if ($num == -1) { + if ($num == - 1) { return ($number != 1) ? $plural : $single; } else { $result = $this->get_translation_string($num); @@ -382,6 +333,56 @@ class Typecho_I18n_GetText } } + /** + * 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; + } + + /** + * 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 (preg_match("/plural\-forms: ([^\n]*)\n/i", $header, $regs)) + $expr = $regs[1]; + else + $expr = "nplurals=2; plural=n == 1 ? 0 : 1;"; + $this->pluralheader = $expr; + } + return $this->pluralheader; + } + /** * 关闭文件句柄 * diff --git a/var/Typecho/I18n/GetTextMulti.php b/var/Typecho/I18n/GetTextMulti.php index 0596b740..0221044b 100644 --- a/var/Typecho/I18n/GetTextMulti.php +++ b/var/Typecho/I18n/GetTextMulti.php @@ -23,7 +23,7 @@ class Typecho_I18n_GetTextMulti * @access private * @var Typecho_I18n_GetText[] */ - private $_handles = array(); + private $_handles = []; /** * 构造函数 @@ -60,7 +60,7 @@ class Typecho_I18n_GetTextMulti { foreach ($this->_handles as $handle) { $string = $handle->translate($string, $count); - if (-1 != $count) { + if (- 1 != $count) { break; } } @@ -79,11 +79,11 @@ class Typecho_I18n_GetTextMulti */ public function ngettext($single, $plural, $number) { - $count = -1; - + $count = - 1; + foreach ($this->_handles as $handle) { $string = $handle->ngettext($single, $plural, $number, $count); - if (-1 != $count) { + if (- 1 != $count) { break; } } diff --git a/var/Typecho/Response.php b/var/Typecho/Response.php index 3d90ae22..a525b358 100644 --- a/var/Typecho/Response.php +++ b/var/Typecho/Response.php @@ -19,6 +19,8 @@ */ class Typecho_Response { + const CHARSET = 'UTF-8'; + /** * http code * @@ -68,17 +70,7 @@ class Typecho_Response 505 => 'HTTP Version Not Supported' ]; - /** - * 字符编码 - * - * @var mixed - * @access private - */ - private $_charset; - //默认的字符编码 - const CHARSET = 'UTF-8'; - /** * 单例句柄 * @@ -94,6 +86,14 @@ class Typecho_Response */ private static $_callbacks = []; + /** + * 字符编码 + * + * @var mixed + * @access private + */ + private $_charset; + /** * 获取单例句柄 * @@ -109,6 +109,106 @@ class Typecho_Response return self::$_instance; } + /** + * 新增回调 + * + * @param $callback + */ + public static function addCallback($callback) + { + self::$_callbacks[] = $callback; + } + + /** + * 设置HTTP状态 + * + * @access public + * @param integer $code http代码 + * @return void + */ + public static function setStatus(int $code) + { + if (isset(self::$_httpCode[$code])) { + header(($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1') + . ' ' . $code . ' ' . self::$_httpCode[$code], true, $code); + } + } + + /** + * 设置http头 + * + * @access public + * @param string $name 名称 + * @param string $value 对应值 + * @return void + */ + public function setHeader(string $name, string $value) + { + header($name . ': ' . $value, true); + } + + /** + * 抛出ajax的回执信息 + * + * @access public + * @param string $message 消息体 + * @return void + */ + public function throwXml(string $message) + { + /** 设置http头信息 */ + $this->setContentType('text/xml'); + + /** 构建消息体 */ + echo 'getCharset() . '"?>', + '', + $this->_parseXml($message), + ''; + + /** 终止后续输出 */ + self::callback(); + exit; + } + + /** + * 在http头部请求中声明类型和字符集 + * + * @access public + * @param string $contentType 文档类型 + * @return void + */ + public function setContentType(string $contentType = 'text/html') + { + header('Content-Type: ' . $contentType . '; charset=' . $this->getCharset(), true); + } + + /** + * 获取字符集 + * + * @access public + * @return string + */ + public function getCharset(): string + { + if (empty($this->_charset)) { + $this->setCharset(); + } + + return $this->_charset; + } + + /** + * 设置默认回执编码 + * + * @access public + * @param string|null $charset 字符集 + * @return void + */ + public function setCharset(string $charset = null) + { + $this->_charset = empty($charset) ? self::CHARSET : $charset; + } + /** * 解析ajax回执的内部函数 * @@ -150,106 +250,6 @@ class Typecho_Response } } - /** - * 新增回调 - * - * @param $callback - */ - public static function addCallback($callback) - { - self::$_callbacks[] = $callback; - } - - /** - * 设置默认回执编码 - * - * @access public - * @param string|null $charset 字符集 - * @return void - */ - public function setCharset(string $charset = null) - { - $this->_charset = empty($charset) ? self::CHARSET : $charset; - } - - /** - * 获取字符集 - * - * @access public - * @return string - */ - public function getCharset(): string - { - if (empty($this->_charset)) { - $this->setCharset(); - } - - return $this->_charset; - } - - /** - * 在http头部请求中声明类型和字符集 - * - * @access public - * @param string $contentType 文档类型 - * @return void - */ - public function setContentType(string $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(string $name, string $value) - { - header($name . ': ' . $value, true); - } - - /** - * 设置HTTP状态 - * - * @access public - * @param integer $code http代码 - * @return void - */ - public static function setStatus(int $code) - { - if (isset(self::$_httpCode[$code])) { - header(($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1') - . ' ' . $code . ' ' . self::$_httpCode[$code], true, $code); - } - } - - /** - * 抛出ajax的回执信息 - * - * @access public - * @param string $message 消息体 - * @return void - */ - public function throwXml(string $message) - { - /** 设置http头信息 */ - $this->setContentType('text/xml'); - - /** 构建消息体 */ - echo 'getCharset() . '"?>', - '', - $this->_parseXml($message), - ''; - - /** 终止后续输出 */ - self::callback(); - exit; - } - /** * 抛出json回执信息 * @@ -269,30 +269,6 @@ class Typecho_Response exit; } - /** - * 重定向函数 - * - * @access public - * @param string $location 重定向路径 - * @param boolean $isPermanently 是否为永久重定向 - * @return void - */ - public function redirect(string $location, bool $isPermanently = false) - { - /** Typecho_Common */ - $location = Typecho_Common::safeUrl($location); - - self::callback(); - - if ($isPermanently) { - header('Location: ' . $location, false, 301); - } else { - header('Location: ' . $location, false, 302); - } - - exit; - } - /** * 返回来路 * @@ -331,11 +307,35 @@ class Typecho_Response } $this->redirect($referer, false); - } else if (!empty($default)) { + } elseif (!empty($default)) { $this->redirect($default); } self::callback(); exit; } + + /** + * 重定向函数 + * + * @access public + * @param string $location 重定向路径 + * @param boolean $isPermanently 是否为永久重定向 + * @return void + */ + public function redirect(string $location, bool $isPermanently = false) + { + /** Typecho_Common */ + $location = Typecho_Common::safeUrl($location); + + self::callback(); + + if ($isPermanently) { + header('Location: ' . $location, false, 301); + } else { + header('Location: ' . $location, false, 302); + } + + exit; + } } diff --git a/var/Typecho/Router/Parser.php b/var/Typecho/Router/Parser.php index 9aed8192..7b6dcaf1 100644 --- a/var/Typecho/Router/Parser.php +++ b/var/Typecho/Router/Parser.php @@ -53,14 +53,14 @@ class Typecho_Router_Parser { $this->_routingTable = $routingTable; - $this->_defaultRegx = array( + $this->_defaultRegx = [ 'string' => '(.%s)', - 'char' => '([^/]%s)', - 'digital'=> '([0-9]%s)', - 'alpha' => '([_0-9a-zA-Z-]%s)', - 'alphaslash' => '([_0-9a-zA-Z-/]%s)', - 'split' => '((?:[^/]+/)%s[^/]+)', - ); + 'char' => '([^/]%s)', + 'digital' => '([0-9]%s)', + 'alpha' => '([_0-9a-zA-Z-]%s)', + 'alphaslash' => '([_0-9a-zA-Z-/]%s)', + 'split' => '((?:[^/]+/)%s[^/]+)', + ]; } /** @@ -78,11 +78,11 @@ class Typecho_Router_Parser if (1 == $paramsNum) { return sprintf($this->_defaultRegx['char'], '+'); - } else if (2 == $paramsNum) { + } elseif (2 == $paramsNum) { return sprintf($this->_defaultRegx[$params[1]], '+'); - } else if (3 == $paramsNum) { + } elseif (3 == $paramsNum) { return sprintf($this->_defaultRegx[$params[1]], $params[2] > 0 ? '{' . $params[2] . '}' : '*'); - } else if (4 == $paramsNum) { + } elseif (4 == $paramsNum) { return sprintf($this->_defaultRegx[$params[1]], '{' . $params[2] . ',' . $params[3] . '}'); } } @@ -95,12 +95,12 @@ class Typecho_Router_Parser */ public function parse() { - $result = array(); + $result = []; 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']))); + $this->_params = []; + $route['regx'] = preg_replace_callback("/%([^%]+)%/", [$this, '_match'], + preg_quote(str_replace(['[', ']', ':'], ['%', '%', ' '], $route['url']))); /** 处理斜线 */ $route['regx'] = rtrim($route['regx'], '/'); diff --git a/var/Typecho/Widget.php b/var/Typecho/Widget.php index ce4abab3..ad036df9 100644 --- a/var/Typecho/Widget.php +++ b/var/Typecho/Widget.php @@ -175,8 +175,8 @@ abstract class Typecho_Widget /** * 释放组件 * - * @deprecated alias for destroy * @param string $alias 组件名称 + * @deprecated alias for destroy */ public static function destory(string $alias) { @@ -257,7 +257,7 @@ abstract class Typecho_Widget { if ($this->sequence < count($this->stack)) { $this->row = $this->stack[$this->sequence]; - $this->sequence++; + $this->sequence ++; } else { $this->sequence = 0; return false; @@ -277,7 +277,7 @@ abstract class Typecho_Widget { //将行数据按顺序置位 $this->row = $value; - $this->length++; + $this->length ++; $this->stack[] = $value; return $value; diff --git a/var/Typecho/Widget/Helper/Form.php b/var/Typecho/Widget/Helper/Form.php index c41e0120..c534cd01 100644 --- a/var/Typecho/Widget/Helper/Form.php +++ b/var/Typecho/Widget/Helper/Form.php @@ -33,7 +33,7 @@ class Typecho_Widget_Helper_Form extends Typecho_Widget_Helper_Layout const MULTIPART_ENCODE = 'multipart/form-data'; /** 文本编码 */ - const TEXT_ENCODE= 'text/plain'; + const TEXT_ENCODE = 'text/plain'; /** * 输入元素列表 @@ -41,14 +41,14 @@ class Typecho_Widget_Helper_Form extends Typecho_Widget_Helper_Layout * @access private * @var array */ - private $_inputs = array(); + private $_inputs = []; /** * 构造函数,设置基本属性 * * @access public */ - public function __construct($action = NULL, $method = self::GET_METHOD, $enctype = self::STANDARD_ENCODE) + public function __construct($action = null, $method = self::GET_METHOD, $enctype = self::STANDARD_ENCODE) { /** 设置表单标签 */ parent::__construct('form'); @@ -62,6 +62,32 @@ class Typecho_Widget_Helper_Form extends Typecho_Widget_Helper_Layout $this->setEncodeType($enctype); } + /** + * 设置表单提交目的 + * + * @access public + * @param string $action 表单提交目的 + * @return Typecho_Widget_Helper_Form + */ + public function setAction($action) + { + $this->setAttribute('action', $action); + return $this; + } + + /** + * 设置表单提交方法 + * + * @access public + * @param string $method 表单提交方法 + * @return Typecho_Widget_Helper_Form + */ + public function setMethod($method) + { + $this->setAttribute('method', $method); + return $this; + } + /** * 设置表单编码方案 * @@ -109,41 +135,15 @@ class Typecho_Widget_Helper_Form extends Typecho_Widget_Helper_Layout */ public function getAllRequest() { - $result = array(); + $result = []; $source = (self::POST_METHOD == $this->getAttribute('method')) ? $_POST : $_GET; foreach ($this->_inputs as $name => $input) { - $result[$name] = isset($source[$name]) ? $source[$name] : NULL; + $result[$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; - } - /** * 获取此表单的所有输入项固有值 * @@ -152,7 +152,7 @@ class Typecho_Widget_Helper_Form extends Typecho_Widget_Helper_Layout */ public function getValues() { - $values = array(); + $values = []; foreach ($this->_inputs as $name => $input) { $values[$name] = $input->value; @@ -171,25 +171,6 @@ class Typecho_Widget_Helper_Form extends Typecho_Widget_Helper_Layout 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; - } - /** * 验证表单 * @@ -199,7 +180,7 @@ class Typecho_Widget_Helper_Form extends Typecho_Widget_Helper_Layout public function validate() { $validator = new Typecho_Validate(); - $rules = array(); + $rules = []; foreach ($this->_inputs as $name => $input) { $rules[$name] = $input->rules; @@ -222,6 +203,25 @@ class Typecho_Widget_Helper_Form extends Typecho_Widget_Helper_Layout return $error; } + /** + * 获取提交数据源 + * + * @access public + * @param array $params 数据参数集 + * @return array + */ + public function getParams(array $params) + { + $result = []; + $source = (self::POST_METHOD == $this->getAttribute('method')) ? $_POST : $_GET; + + foreach ($params as $param) { + $result[$param] = $source[$param] ?? null; + } + + return $result; + } + /** * 显示表单 * @@ -239,7 +239,7 @@ class Typecho_Widget_Helper_Form extends Typecho_Widget_Helper_Layout $record = Json::decode($record, true); $message = Json::decode($message, true); foreach ($this->_inputs as $name => $input) { - $input->value(isset($record[$name]) ? $record[$name] : $input->value); + $input->value($record[$name] ?? $input->value); /** 显示错误消息 */ if (isset($message[$name])) { diff --git a/var/Typecho/Widget/Helper/Form/Element.php b/var/Typecho/Widget/Helper/Form/Element.php index 3b5e11ad..34e2f3ac 100644 --- a/var/Typecho/Widget/Helper/Form/Element.php +++ b/var/Typecho/Widget/Helper/Form/Element.php @@ -20,30 +20,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_Layout { - /** - * 表单描述 - * - * @access private - * @var string - */ - protected $description; - - /** - * 表单消息 - * - * @access protected - * @var string - */ - protected $message; - - /** - * 多行输入 - * - * @access public - * @var array() - */ - protected $multiline = array(); - /** * 单例唯一id * @@ -51,7 +27,6 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ * @var integer */ protected static $uniqueId = 0; - /** * 表单元素容器 * @@ -59,7 +34,6 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ * @var Typecho_Widget_Helper_Layout */ public $container; - /** * 输入栏 * @@ -67,15 +41,13 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ * @var Typecho_Widget_Helper_Layout */ public $input; - /** - * inputs - * + * inputs + * * @var array * @access public */ - public $inputs = array(); - + public $inputs = []; /** * 表单标题 * @@ -83,15 +55,13 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ * @var Typecho_Widget_Helper_Layout */ public $label; - /** * 表单验证器 * * @access public * @var array */ - public $rules = array(); - + public $rules = []; /** * 表单名称 * @@ -99,7 +69,6 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ * @var string */ public $name; - /** * 表单值 * @@ -107,6 +76,27 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ * @var mixed */ public $value; + /** + * 表单描述 + * + * @access private + * @var string + */ + protected $description; + /** + * 表单消息 + * + * @access protected + * @var string + */ + protected $message; + /** + * 多行输入 + * + * @access public + * @var array() + */ + protected $multiline = []; /** * 构造函数 @@ -119,10 +109,10 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ * @param string $description 表单描述 * @return void */ - public function __construct($name = NULL, array $options = NULL, $value = NULL, $label = NULL, $description = NULL) + public function __construct($name = null, array $options = null, $value = null, $label = null, $description = null) { /** 创建html元素,并设置class */ - parent::__construct('ul', array('class' => 'typecho-option', 'id' => 'typecho-option-item-' . $name . '-' . self::$uniqueId)); + parent::__construct('ul', ['class' => 'typecho-option', 'id' => 'typecho-option-item-' . $name . '-' . self::$uniqueId]); $this->name = $name; self::$uniqueId ++; @@ -130,7 +120,7 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ $this->init(); /** 初始化表单标题 */ - if (NULL !== $label) { + if (null !== $label) { $this->label($label); } @@ -138,39 +128,25 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ $this->input = $this->input($name, $options); /** 初始化表单值 */ - if (NULL !== $value) { + if (null !== $value) { $this->value($value); } /** 初始化表单描述 */ - if (NULL !== $description) { + 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(){} + public function init() + { + } /** * 创建表单标题 @@ -183,7 +159,7 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ { /** 创建标题元素 */ if (empty($this->label)) { - $this->label = new Typecho_Widget_Helper_Layout('label', array('class' => 'typecho-label')); + $this->label = new Typecho_Widget_Helper_Layout('label', ['class' => 'typecho-label']); $this->container($this->label); } @@ -211,41 +187,15 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ } /** - * 设置提示信息 + * 初始化当前输入项 * * @access public - * @param string $message 提示信息 + * @param Typecho_Widget_Helper_Layout $container 容器对象 + * @param string $name 表单元素名称 + * @param array $options 选择项 * @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; - } + abstract public function input($name = null, array $options = null); /** * 设置表单元素值 @@ -261,6 +211,52 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ return $this; } + /** + * 设置表单元素值 + * + * @access protected + * @param mixed $value 表单元素值 + * @return void + */ + abstract protected function _value($value); + + /** + * 设置描述信息 + * + * @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', ['class' => 'description']); + $this->container($this->description); + } + + $this->description->html($description); + 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', ['class' => 'message error']); + $this->container($this->message); + } + + $this->message->html($message); + return $this; + } + /** * 多行输出模式 * @@ -288,26 +284,6 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ 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); - /** * 增加验证器 * @@ -332,4 +308,20 @@ abstract class Typecho_Widget_Helper_Form_Element extends Typecho_Widget_Helper_ $input->setAttribute($attributeName, $attributeValue); } } + + /** + * 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 ''; + } } diff --git a/var/Typecho/Widget/Helper/Form/Element/Checkbox.php b/var/Typecho/Widget/Helper/Form/Element/Checkbox.php index 8ae5265a..2caf3c1f 100644 --- a/var/Typecho/Widget/Helper/Form/Element/Checkbox.php +++ b/var/Typecho/Widget/Helper/Form/Element/Checkbox.php @@ -26,7 +26,7 @@ class Typecho_Widget_Helper_Form_Element_Checkbox extends Typecho_Widget_Helper_ * @access private * @var array */ - private $_options = array(); + private $_options = []; /** * 初始化当前输入项 @@ -36,7 +36,7 @@ class Typecho_Widget_Helper_Form_Element_Checkbox extends Typecho_Widget_Helper_ * @param array $options 选择项 * @return Typecho_Widget_Helper_Layout */ - public function input($name = NULL, array $options = NULL) + public function input($name = null, array $options = null) { foreach ($options as $value => $label) { $this->_options[$value] = new Typecho_Widget_Helper_Layout('input'); @@ -45,9 +45,9 @@ class Typecho_Widget_Helper_Form_Element_Checkbox extends Typecho_Widget_Helper_ $this->inputs[] = $this->_options[$value]; $item->addItem($this->_options[$value]->setAttribute('name', $this->name . '[]') - ->setAttribute('type', 'checkbox') - ->setAttribute('value', $value) - ->setAttribute('id', $id)); + ->setAttribute('type', 'checkbox') + ->setAttribute('value', $value) + ->setAttribute('id', $id)); $labelItem = new Typecho_Widget_Helper_Layout('label'); $item->addItem($labelItem->setAttribute('for', $id)->html($label)); @@ -66,7 +66,7 @@ class Typecho_Widget_Helper_Form_Element_Checkbox extends Typecho_Widget_Helper_ */ protected function _value($value) { - $values = is_array($value) ? $value : array($value); + $values = is_array($value) ? $value : [$value]; foreach ($this->_options as $option) { $option->removeAttribute('checked'); diff --git a/var/Typecho/Widget/Helper/Form/Element/Fake.php b/var/Typecho/Widget/Helper/Form/Element/Fake.php index 3bbf128f..ce460d90 100644 --- a/var/Typecho/Widget/Helper/Form/Element/Fake.php +++ b/var/Typecho/Widget/Helper/Form/Element/Fake.php @@ -40,7 +40,7 @@ class Typecho_Widget_Helper_Form_Element_Fake extends Typecho_Widget_Helper_Form $this->input = $this->input($name); /** 初始化表单值 */ - if (NULL !== $value) { + if (null !== $value) { $this->value($value); } } @@ -52,7 +52,8 @@ class Typecho_Widget_Helper_Form_Element_Fake extends Typecho_Widget_Helper_Form * @return void */ public function init() - {} + { + } /** * 初始化当前输入项 @@ -62,7 +63,7 @@ class Typecho_Widget_Helper_Form_Element_Fake extends Typecho_Widget_Helper_Form * @param array $options 选择项 * @return Typecho_Widget_Helper_Layout */ - public function input($name = NULL, array $options = NULL) + public function input($name = null, array $options = null) { $input = new Typecho_Widget_Helper_Layout('input'); $this->inputs[] = $input; diff --git a/var/Typecho/Widget/Helper/Form/Element/Hidden.php b/var/Typecho/Widget/Helper/Form/Element/Hidden.php index c3c92149..38af0efb 100644 --- a/var/Typecho/Widget/Helper/Form/Element/Hidden.php +++ b/var/Typecho/Widget/Helper/Form/Element/Hidden.php @@ -40,9 +40,9 @@ class Typecho_Widget_Helper_Form_Element_Hidden extends Typecho_Widget_Helper_Fo * @param array $options 选择项 * @return Typecho_Widget_Helper_Layout */ - public function input($name = NULL, array $options = NULL) + public function input($name = null, array $options = null) { - $input = new Typecho_Widget_Helper_Layout('input', array('name' => $name, 'type' => 'hidden')); + $input = new Typecho_Widget_Helper_Layout('input', ['name' => $name, 'type' => 'hidden']); $this->container($input); $this->inputs[] = $input; return $input; diff --git a/var/Typecho/Widget/Helper/Form/Element/Password.php b/var/Typecho/Widget/Helper/Form/Element/Password.php index 347a540e..072991a8 100644 --- a/var/Typecho/Widget/Helper/Form/Element/Password.php +++ b/var/Typecho/Widget/Helper/Form/Element/Password.php @@ -28,10 +28,10 @@ class Typecho_Widget_Helper_Form_Element_Password extends Typecho_Widget_Helper_ * @param array $options 选择项 * @return Typecho_Widget_Helper_Layout */ - public function input($name = NULL, array $options = NULL) + public function input($name = null, array $options = null) { - $input = new Typecho_Widget_Helper_Layout('input', array('id' => $name . '-0-' . self::$uniqueId, - 'name' => $name, 'type' => 'password', 'class' => 'password')); + $input = new Typecho_Widget_Helper_Layout('input', ['id' => $name . '-0-' . self::$uniqueId, + 'name' => $name, 'type' => 'password', 'class' => 'password']); $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); $this->container($input); $this->inputs[] = $input; diff --git a/var/Typecho/Widget/Helper/Form/Element/Radio.php b/var/Typecho/Widget/Helper/Form/Element/Radio.php index c487b79f..61803038 100644 --- a/var/Typecho/Widget/Helper/Form/Element/Radio.php +++ b/var/Typecho/Widget/Helper/Form/Element/Radio.php @@ -26,7 +26,7 @@ class Typecho_Widget_Helper_Form_Element_Radio extends Typecho_Widget_Helper_For * @access private * @var array */ - private $_options = array(); + private $_options = []; /** * 初始化当前输入项 @@ -36,7 +36,7 @@ class Typecho_Widget_Helper_Form_Element_Radio extends Typecho_Widget_Helper_For * @param array $options 选择项 * @return Typecho_Widget_Helper_Layout */ - public function input($name = NULL, array $options = NULL) + public function input($name = null, array $options = null) { foreach ($options as $value => $label) { $this->_options[$value] = new Typecho_Widget_Helper_Layout('input'); @@ -45,9 +45,9 @@ class Typecho_Widget_Helper_Form_Element_Radio extends Typecho_Widget_Helper_For $this->inputs[] = $this->_options[$value]; $item->addItem($this->_options[$value]->setAttribute('name', $this->name) - ->setAttribute('type', 'radio') - ->setAttribute('value', $value) - ->setAttribute('id', $id)); + ->setAttribute('type', 'radio') + ->setAttribute('value', $value) + ->setAttribute('id', $id)); $labelItem = new Typecho_Widget_Helper_Layout('label'); $item->addItem($labelItem->setAttribute('for', $id)->html($label)); diff --git a/var/Typecho/Widget/Helper/Form/Element/Select.php b/var/Typecho/Widget/Helper/Form/Element/Select.php index e589990c..5fa9b84d 100644 --- a/var/Typecho/Widget/Helper/Form/Element/Select.php +++ b/var/Typecho/Widget/Helper/Form/Element/Select.php @@ -26,7 +26,7 @@ class Typecho_Widget_Helper_Form_Element_Select extends Typecho_Widget_Helper_Fo * @access private * @var array */ - private $_options = array(); + private $_options = []; /** * 初始化当前输入项 @@ -36,11 +36,11 @@ class Typecho_Widget_Helper_Form_Element_Select extends Typecho_Widget_Helper_Fo * @param array $options 选择项 * @return Typecho_Widget_Helper_Layout */ - public function input($name = NULL, array $options = NULL) + public function input($name = null, array $options = null) { $input = new Typecho_Widget_Helper_Layout('select'); $this->container($input->setAttribute('name', $name) - ->setAttribute('id', $name . '-0-' . self::$uniqueId)); + ->setAttribute('id', $name . '-0-' . self::$uniqueId)); $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); $this->inputs[] = $input; diff --git a/var/Typecho/Widget/Helper/Form/Element/Submit.php b/var/Typecho/Widget/Helper/Form/Element/Submit.php index 1272f7cf..93eabefa 100644 --- a/var/Typecho/Widget/Helper/Form/Element/Submit.php +++ b/var/Typecho/Widget/Helper/Form/Element/Submit.php @@ -28,10 +28,10 @@ class Typecho_Widget_Helper_Form_Element_Submit extends Typecho_Widget_Helper_Fo * @param array $options 选择项 * @return Typecho_Widget_Helper_Layout */ - public function input($name = NULL, array $options = NULL) + public function input($name = null, array $options = null) { $this->setAttribute('class', 'typecho-option typecho-option-submit'); - $input = new Typecho_Widget_Helper_Layout('button', array('type' => 'submit')); + $input = new Typecho_Widget_Helper_Layout('button', ['type' => 'submit']); $this->container($input); $this->inputs[] = $input; diff --git a/var/Typecho/Widget/Helper/Form/Element/Text.php b/var/Typecho/Widget/Helper/Form/Element/Text.php index 78d1939c..8f30c2a3 100644 --- a/var/Typecho/Widget/Helper/Form/Element/Text.php +++ b/var/Typecho/Widget/Helper/Form/Element/Text.php @@ -28,10 +28,10 @@ class Typecho_Widget_Helper_Form_Element_Text extends Typecho_Widget_Helper_Form * @param array $options 选择项 * @return Typecho_Widget_Helper_Layout */ - public function input($name = NULL, array $options = NULL) + public function input($name = null, array $options = null) { - $input = new Typecho_Widget_Helper_Layout('input', array('id' => $name . '-0-' . self::$uniqueId, - 'name' => $name, 'type' => 'text', 'class' => 'text')); + $input = new Typecho_Widget_Helper_Layout('input', ['id' => $name . '-0-' . self::$uniqueId, + 'name' => $name, 'type' => 'text', 'class' => 'text']); $this->container($input); $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); $this->inputs[] = $input; diff --git a/var/Typecho/Widget/Helper/Form/Element/Textarea.php b/var/Typecho/Widget/Helper/Form/Element/Textarea.php index ec5adacd..b09d5c4e 100644 --- a/var/Typecho/Widget/Helper/Form/Element/Textarea.php +++ b/var/Typecho/Widget/Helper/Form/Element/Textarea.php @@ -28,9 +28,9 @@ class Typecho_Widget_Helper_Form_Element_Textarea extends Typecho_Widget_Helper_ * @param array $options 选择项 * @return Typecho_Widget_Helper_Layout */ - public function input($name = NULL, array $options = NULL) + public function input($name = null, array $options = null) { - $input = new Typecho_Widget_Helper_Layout('textarea', array('id' => $name . '-0-' . self::$uniqueId, 'name' => $name)); + $input = new Typecho_Widget_Helper_Layout('textarea', ['id' => $name . '-0-' . self::$uniqueId, 'name' => $name]); $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); $this->container($input->setClose(false)); $this->inputs[] = $input; diff --git a/var/Typecho/Widget/Helper/Layout.php b/var/Typecho/Widget/Helper/Layout.php index b90c081e..e0acddc2 100644 --- a/var/Typecho/Widget/Helper/Layout.php +++ b/var/Typecho/Widget/Helper/Layout.php @@ -25,7 +25,7 @@ class Typecho_Widget_Helper_Layout * @access private * @var array */ - private $_items = array(); + private $_items = []; /** * 表单属性列表 @@ -33,7 +33,7 @@ class Typecho_Widget_Helper_Layout * @access private * @var array */ - private $_attributes = array(); + private $_attributes = []; /** * 标签名称 @@ -57,7 +57,7 @@ class Typecho_Widget_Helper_Layout * @access private * @var boolean */ - private $_forceClose = NULL; + private $_forceClose = null; /** * 内部数据 @@ -83,7 +83,7 @@ class Typecho_Widget_Helper_Layout * @param array $attributes 属性列表 * @return void */ - public function __construct($tagName = 'div', array $attributes = NULL) + public function __construct($tagName = 'div', array $attributes = null) { $this->setTagName($tagName); @@ -95,16 +95,16 @@ class Typecho_Widget_Helper_Layout } /** - * 增加元素 + * 设置表单属性 * * @access public - * @param Typecho_Widget_Helper_Layout $item 元素 + * @param string $attributeName 属性名称 + * @param string $attributeValue 属性值 * @return Typecho_Widget_Helper_Layout */ - public function addItem(Typecho_Widget_Helper_Layout $item) + public function setAttribute($attributeName, $attributeValue) { - $item->setParent($this); - $this->_items[] = $item; + $this->_attributes[$attributeName] = $attributeValue; return $this; } @@ -122,8 +122,8 @@ class Typecho_Widget_Helper_Layout } /** - * getItems - * + * getItems + * * @access public * @return array */ @@ -133,26 +133,14 @@ class Typecho_Widget_Helper_Layout } /** - * 设置内部数据 + * getTagName * + * @param mixed $tagName * @access public - * @param mixed $html 内部数据 - * @return unknown + * @return void */ - public function html($html = false) + public function getTagName($tagName) { - if (false === $html) { - if (empty($this->_html)) { - foreach ($this->_items as $item) { - $item->render(); - } - } else { - echo $this->_html; - } - } else { - $this->_html = $html; - return $this; - } } /** @@ -166,30 +154,6 @@ class Typecho_Widget_Helper_Layout { $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; - } /** * 移除某个属性 @@ -216,7 +180,7 @@ class Typecho_Widget_Helper_Layout */ public function getAttribute($attributeName) { - return isset($this->_attributes[$attributeName]) ? $this->_attributes[$attributeName] : NULL; + return $this->_attributes[$attributeName] ?? null; } /** @@ -232,6 +196,17 @@ class Typecho_Widget_Helper_Layout return $this; } + /** + * 获取父节点 + * + * @access public + * @return Typecho_Widget_Helper_Layout + */ + public function getParent() + { + return $this->_parent; + } + /** * 设置父节点 * @@ -245,17 +220,6 @@ class Typecho_Widget_Helper_Layout return $this; } - /** - * 获取父节点 - * - * @access public - * @return Typecho_Widget_Helper_Layout - */ - public function getParent() - { - return $this->_parent; - } - /** * 增加到某布局元素集合中 * @@ -270,38 +234,29 @@ class Typecho_Widget_Helper_Layout } /** - * 开始标签 + * 增加元素 * * @access public - * @return void + * @param Typecho_Widget_Helper_Layout $item 元素 + * @return Typecho_Widget_Helper_Layout */ - public function start() + public function addItem(Typecho_Widget_Helper_Layout $item) { - /** 输出标签 */ - echo $this->_tagName ? "<{$this->_tagName}" : NULL; - - /** 输出属性 */ - foreach ($this->_attributes as $attributeName => $attributeValue) { - echo " {$attributeName}=\"{$attributeValue}\""; - } - - /** 支持自闭合 */ - if (!$this->_close && $this->_tagName) { - echo ">\n"; - } + $item->setParent($this); + $this->_items[] = $item; + return $this; } /** - * 结束标签 + * 获取属性 * * @access public + * @param string $attributeName 属性名称 * @return void */ - public function end() + public function __get($name) { - if ($this->_tagName) { - echo $this->_close ? " />\n" : "_tagName}>\n"; - } + return $this->_attributes[$name] ?? null; } /** @@ -317,18 +272,6 @@ class Typecho_Widget_Helper_Layout $this->_attributes[$name] = $value; } - /** - * 获取属性 - * - * @access public - * @param string $attributeName 属性名称 - * @return void - */ - public function __get($name) - { - return isset($this->_attributes[$name]) ? $this->_attributes[$name] : NULL; - } - /** * 输出所有元素 * @@ -341,7 +284,7 @@ class Typecho_Widget_Helper_Layout $this->_close = true; } - if (NULL !== $this->_forceClose) { + if (null !== $this->_forceClose) { $this->_close = $this->_forceClose; } @@ -349,4 +292,62 @@ class Typecho_Widget_Helper_Layout $this->html(); $this->end(); } + + /** + * 开始标签 + * + * @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 + * @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 + * @return void + */ + public function end() + { + if ($this->_tagName) { + echo $this->_close ? " />\n" : "_tagName}>\n"; + } + } } diff --git a/var/Typecho/Widget/Helper/PageNavigator.php b/var/Typecho/Widget/Helper/PageNavigator.php index 12d5b96b..b35b559a 100644 --- a/var/Typecho/Widget/Helper/PageNavigator.php +++ b/var/Typecho/Widget/Helper/PageNavigator.php @@ -68,7 +68,7 @@ abstract class Typecho_Widget_Helper_PageNavigator * @access protected * @var mixed */ - protected $_pageHolder = array('{page}', '%7Bpage%7D'); + protected $_pageHolder = ['{page}', '%7Bpage%7D']; /** * 构造函数,初始化页面基本信息 @@ -102,8 +102,8 @@ abstract class Typecho_Widget_Helper_PageNavigator */ public function setPageHolder($holder) { - $this->_pageHolder = array('{' . $holder . '}', - str_replace(array('{', '}'), array('%7B', '%7D'), $holder)); + $this->_pageHolder = ['{' . $holder . '}', + str_replace(['{', '}'], ['%7B', '%7D'], $holder)]; } /** diff --git a/var/Typecho/Widget/Helper/PageNavigator/Box.php b/var/Typecho/Widget/Helper/PageNavigator/Box.php index 57b9df47..3a22114b 100644 --- a/var/Typecho/Widget/Helper/PageNavigator/Box.php +++ b/var/Typecho/Widget/Helper/PageNavigator/Box.php @@ -30,30 +30,30 @@ class Typecho_Widget_Helper_PageNavigator_Box extends Typecho_Widget_Helper_Page * @param string $currentClass 当前激活元素class * @return void */ - public function render($prevWord = 'PREV', $nextWord = 'NEXT', $splitPage = 3, $splitWord = '...', array $template = array()) - { + public function render($prevWord = 'PREV', $nextWord = 'NEXT', $splitPage = 3, $splitWord = '...', array $template = []) + { if ($this->_total < 1) { return; } - $default = array( - 'itemTag' => 'li', - 'textTag' => 'span', - 'currentClass' => 'current', - 'prevClass' => 'prev', - 'nextClass' => 'next' - ); + $default = [ + 'itemTag' => 'li', + 'textTag' => 'span', + 'currentClass' => 'current', + 'prevClass' => 'prev', + 'nextClass' => 'next' + ]; $template = array_merge($default, $template); extract($template); // 定义item $itemBegin = empty($itemTag) ? '' : ('<' . $itemTag . '>'); - $itemCurrentBegin = empty($itemTag) ? '' : ('<' . $itemTag + $itemCurrentBegin = empty($itemTag) ? '' : ('<' . $itemTag . (empty($currentClass) ? '' : ' class="' . $currentClass . '"') . '>'); - $itemPrevBegin = empty($itemTag) ? '' : ('<' . $itemTag + $itemPrevBegin = empty($itemTag) ? '' : ('<' . $itemTag . (empty($prevClass) ? '' : ' class="' . $prevClass . '"') . '>'); - $itemNextBegin = empty($itemTag) ? '' : ('<' . $itemTag + $itemNextBegin = empty($itemTag) ? '' : ('<' . $itemTag . (empty($nextClass) ? '' : ' class="' . $nextClass . '"') . '>'); $itemEnd = empty($itemTag) ? '' : (''); $textBegin = empty($textTag) ? '' : ('<' . $textTag . '>'); @@ -76,7 +76,7 @@ class Typecho_Widget_Helper_PageNavigator_Box extends Typecho_Widget_Helper_Page //输出上一页 if ($this->_currentPage > 1) { echo $itemPrevBegin . sprintf($linkPrevBegin, - str_replace($this->_pageHolder, $this->_currentPage - 1, $this->_pageTemplate) . $this->_anchor) + str_replace($this->_pageHolder, $this->_currentPage - 1, $this->_pageTemplate) . $this->_anchor) . $prevWord . $linkEnd . $itemEnd; } @@ -94,9 +94,9 @@ class Typecho_Widget_Helper_PageNavigator_Box extends Typecho_Widget_Helper_Page //输出中间页 for ($i = $from; $i <= $to; $i ++) { $current = ($i == $this->_currentPage); - + echo ($current ? $itemCurrentBegin : $itemBegin) . sprintf(($current ? $linkCurrentBegin : $linkBegin), - str_replace($this->_pageHolder, $i, $this->_pageTemplate) . $this->_anchor) + str_replace($this->_pageHolder, $i, $this->_pageTemplate) . $this->_anchor) . $i . $linkEnd . $itemEnd; } @@ -105,7 +105,7 @@ class Typecho_Widget_Helper_PageNavigator_Box extends Typecho_Widget_Helper_Page if ($to < $this->_totalPage - 1) { echo $itemBegin . $textBegin . $splitWord . $textEnd . $itemEnd; } - + echo $itemBegin . sprintf($linkBegin, str_replace($this->_pageHolder, $this->_totalPage, $this->_pageTemplate) . $this->_anchor) . $this->_totalPage . $linkEnd . $itemEnd; } @@ -113,7 +113,7 @@ class Typecho_Widget_Helper_PageNavigator_Box extends Typecho_Widget_Helper_Page //输出下一页 if ($this->_currentPage < $this->_totalPage) { echo $itemNextBegin . sprintf($linkNextBegin, - str_replace($this->_pageHolder, $this->_currentPage + 1, $this->_pageTemplate) . $this->_anchor) + str_replace($this->_pageHolder, $this->_currentPage + 1, $this->_pageTemplate) . $this->_anchor) . $nextWord . $linkEnd . $itemEnd; } } diff --git a/var/Typecho/Widget/Helper/PageNavigator/Classic.php b/var/Typecho/Widget/Helper/PageNavigator/Classic.php index d90bba09..52231842 100644 --- a/var/Typecho/Widget/Helper/PageNavigator/Classic.php +++ b/var/Typecho/Widget/Helper/PageNavigator/Classic.php @@ -45,7 +45,7 @@ class Typecho_Widget_Helper_PageNavigator_Classic extends Typecho_Widget_Helper_ //输出上一页 if ($this->_total > 0 && $this->_currentPage > 1) { echo ''; + . $prevWord . ''; } } @@ -61,7 +61,7 @@ class Typecho_Widget_Helper_PageNavigator_Classic extends Typecho_Widget_Helper_ //输出下一页 if ($this->_total > 0 && $this->_currentPage < $this->_totalPage) { echo ''; + . $nextWord . ''; } } } diff --git a/var/Upgrade.php b/var/Upgrade.php index 6fdf62cd..b29111f3 100644 --- a/var/Upgrade.php +++ b/var/Upgrade.php @@ -34,15 +34,15 @@ class Upgrade while (true) { $result = $db->query($db->select('coid', 'text')->from('table.comments') - ->order('coid', Typecho_Db::SORT_ASC)->page($i, 100)); + ->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'])); + ->rows(['text' => $text]) + ->where('coid = ?', $row['coid'])); $j ++; unset($text); @@ -62,19 +62,19 @@ class Upgrade while (true) { $result = $db->query($db->select('cid', 'text')->from('table.contents') - ->order('cid', Typecho_Db::SORT_ASC)->page($i, 100)); + ->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']); + ["/\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"], + ['', "\n\n", "\n", "\n\n<\\1>", "\n\n"], + $row['text']); $db->query($db->update('table.contents') - ->rows(array('text' => $text)) - ->where('cid = ?', $row['cid'])); + ->rows(['text' => $text]) + ->where('cid = ?', $row['cid'])); $j ++; unset($text); @@ -127,15 +127,15 @@ Typecho_Date::setTimezoneOffset($options->timezone); while (true) { $result = $db->query($db->select('coid', 'text')->from('table.comments') - ->order('coid', Typecho_Db::SORT_ASC)->page($i, 100)); + ->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'])); + ->rows(['text' => $text]) + ->where('coid = ?', $row['coid'])); $j ++; unset($text); @@ -163,8 +163,8 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 升级编辑器接口 */ $db->query($db->update('table.options') - ->rows(array('value' => 350)) - ->where('name = ?', 'editorSize')); + ->rows(['value' => 350]) + ->where('name = ?', 'editorSize')); } /** @@ -179,7 +179,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 升级编辑器接口 */ $db->query($db->insert('table.options') - ->rows(array('name' => 'useRichEditor', 'user' => 0, 'value' => 1))); + ->rows(['name' => 'useRichEditor', 'user' => 0, 'value' => 1])); } /** @@ -194,7 +194,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 修改数据库字段 */ $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); + $prefix = $db->getPrefix(); //删除老数据 try { @@ -361,23 +361,23 @@ Typecho_Date::setTimezoneOffset($options->timezone); /** 增加自定义主页 */ $db->query($db->insert('table.options') - ->rows(array('name' => 'customHomePage', 'user' => 0, 'value' => 0))); + ->rows(['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";}'))); + ->rows(['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";}'))); + ->rows(['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";}'))); + ->rows(['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'))); + ->rows(['name' => 'attachmentTypes', 'user' => 0, 'value' => '*.jpg;*.gif;*.png;*.zip;*.tar.gz'])); /** 增加路由 */ $routingTable = $options->routingTable; @@ -388,16 +388,16 @@ Typecho_Date::setTimezoneOffset($options->timezone); $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); + $routingTable = array_merge($pre, ['attachment' => + [ + 'url' => '/attachment/[cid:digital]/', + 'widget' => 'Widget_Archive', + 'action' => 'render', + ]], $next); $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); + ->rows(['value' => serialize($routingTable)]) + ->where('name = ?', 'routingTable')); } /** @@ -412,16 +412,16 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 去掉所见即所得编辑器 */ $db->query($db->delete('table.options') - ->where('name = ?', 'useRichEditor')); + ->where('name = ?', 'useRichEditor')); /** 修正自动保存值 */ $db->query($db->update('table.options') - ->rows(array('value' => 0)) - ->where('name = ?', 'autoSave')); + ->rows(['value' => 0]) + ->where('name = ?', 'autoSave')); /** 增加堆楼楼层数目限制 */ $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsMaxNestingLevels', 'user' => 0, 'value' => 5))); + ->rows(['name' => 'commentsMaxNestingLevels', 'user' => 0, 'value' => 5])); } /** @@ -436,29 +436,29 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 增加附件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";}'))); + ->rows(['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";}'))); + ->rows(['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)); + ->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'); + $attachment['modifyHandle'] = ['Widget_Upload', 'modifyHandle']; + $attachment['attachmentDataHandle'] = ['Widget_Upload', 'attachmentDataHandle']; $db->query($db->update('table.contents') - ->rows(array('text' => serialize($attachment))) - ->where('cid = ?', $row['cid'])); + ->rows(['text' => serialize($attachment)]) + ->where('cid = ?', $row['cid'])); $j ++; unset($text); @@ -490,20 +490,20 @@ Typecho_Date::setTimezoneOffset($options->timezone); unset($routingTable[0]); } - $routingTable['do'] = array ( + $routingTable['do'] = [ 'url' => '/action/[action:alpha]', 'widget' => 'Widget_Do', 'action' => 'action' - ); + ]; $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); + ->rows(['value' => serialize($routingTable)]) + ->where('name = ?', 'routingTable')); //干掉垃圾数据 $db->query($db->update('table.options') - ->rows(array('value' => 'a:0:{}')) - ->where('name = ?', 'actionTable')); + ->rows(['value' => 'a:0:{}']) + ->where('name = ?', 'actionTable')); } /** @@ -518,14 +518,14 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 增加默认内容格式 */ $db->query($db->insert('table.options') - ->rows(array('name' => 'contentType', 'user' => 0, 'value' => 'text/html'))); + ->rows(['name' => 'contentType', 'user' => 0, 'value' => 'text/html'])); /** 增加gzip开关 */ $db->query($db->insert('table.options') - ->rows(array('name' => 'gzip', 'user' => 0, 'value' => 0))); + ->rows(['name' => 'gzip', 'user' => 0, 'value' => 0])); - if(is_writeable(__TYPECHO_ROOT_DIR__ . '/config.inc.php')) { + 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( @@ -557,7 +557,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); public static function v0_7r9_9_2($db, $options) { $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); + $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); @@ -587,11 +587,11 @@ Typecho_Date::setTimezoneOffset($options->timezone); $pre = array_slice($routingTable, 0, 1); $next = array_slice($routingTable, 1); - $routingTable = array_merge($pre, array('do' => $do), $next); + $routingTable = array_merge($pre, ['do' => $do], $next); $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); + ->rows(['value' => serialize($routingTable)]) + ->where('name = ?', 'routingTable')); } /** @@ -611,11 +611,11 @@ Typecho_Date::setTimezoneOffset($options->timezone); unset($routingTable[0]); } - $routingTable['do'] = array ( + $routingTable['do'] = [ 'url' => '/action/[action:alpha]', 'widget' => 'Widget_Do', 'action' => 'action' - ); + ]; $do = $routingTable['do']; unset($routingTable['do']); @@ -623,11 +623,11 @@ Typecho_Date::setTimezoneOffset($options->timezone); $pre = array_slice($routingTable, 0, 1); $next = array_slice($routingTable, 1); - $routingTable = array_merge($pre, array('do' => $do), $next); + $routingTable = array_merge($pre, ['do' => $do], $next); $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); + ->rows(['value' => serialize($routingTable)]) + ->where('name = ?', 'routingTable')); } /** @@ -652,24 +652,24 @@ Typecho_Date::setTimezoneOffset($options->timezone); $next_pre = array_slice($next, 0, 5); $next_next = array_slice($next, 5); - $author = array ( + $author = [ 'url' => '/author/[uid:digital]/', 'widget' => 'Widget_Archive', 'action' => 'render', - ); + ]; - $author_page = array ( + $author_page = [ '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); + $routingTable = array_merge($pre, ['author' => $author], $next_pre, + ['author_page' => $author_page], $next_next); $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); + ->rows(['value' => serialize($routingTable)]) + ->where('name = ?', 'routingTable')); } /** @@ -692,17 +692,17 @@ Typecho_Date::setTimezoneOffset($options->timezone); $pre = array_slice($routingTable, 0, 20); $next = array_slice($routingTable, 20); - $commentPage = array ( + $commentPage = [ 'url' => '[permalink:string]/[commentType:alpha]-page-[commentPage:digital]', 'widget' => 'Widget_Archive', 'action' => 'render', - ); + ]; - $routingTable = array_merge($pre, array('comment_page' => $commentPage), $next); + $routingTable = array_merge($pre, ['comment_page' => $commentPage], $next); $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); + ->rows(['value' => serialize($routingTable)]) + ->where('name = ?', 'routingTable')); } /** @@ -718,7 +718,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 修改数据库字段 */ $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); + $prefix = $db->getPrefix(); switch (true) { case false !== strpos($adapterName, 'Mysql'): @@ -784,10 +784,10 @@ Typecho_Date::setTimezoneOffset($options->timezone); } $db->query($db->update('table.contents')->expression('parent', 'order') - ->where('type = ?', 'attachment')); + ->where('type = ?', 'attachment')); - $db->query($db->update('table.contents')->rows(array('order' => 0)) - ->where('type = ?', 'attachment')); + $db->query($db->update('table.contents')->rows(['order' => 0]) + ->where('type = ?', 'attachment')); } /** @@ -801,8 +801,8 @@ Typecho_Date::setTimezoneOffset($options->timezone); */ public static function v0_7r9_10_31($db, $options) { - $db->query($db->update('table.contents')->rows(array('status' => 'publish')) - ->where('type = ?', 'attachment')); + $db->query($db->update('table.contents')->rows(['status' => 'publish']) + ->where('type = ?', 'attachment')); } /** @@ -817,34 +817,34 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 增加若干选项 */ $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPageBreak', 'user' => 0, 'value' => 0))); + ->rows(['name' => 'commentsPageBreak', 'user' => 0, 'value' => 0])); $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsThreaded', 'user' => 0, 'value' => 1))); + ->rows(['name' => 'commentsThreaded', 'user' => 0, 'value' => 1])); $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPageSize', 'user' => 0, 'value' => 20))); + ->rows(['name' => 'commentsPageSize', 'user' => 0, 'value' => 20])); $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPageDisplay', 'user' => 0, 'value' => 'last'))); + ->rows(['name' => 'commentsPageDisplay', 'user' => 0, 'value' => 'last'])); $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsOrder', 'user' => 0, 'value' => 'ASC'))); + ->rows(['name' => 'commentsOrder', 'user' => 0, 'value' => 'ASC'])); $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsCheckReferer', 'user' => 0, 'value' => 1))); + ->rows(['name' => 'commentsCheckReferer', 'user' => 0, 'value' => 1])); $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsAutoClose', 'user' => 0, 'value' => 0))); + ->rows(['name' => 'commentsAutoClose', 'user' => 0, 'value' => 0])); $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPostIntervalEnable', 'user' => 0, 'value' => 1))); + ->rows(['name' => 'commentsPostIntervalEnable', 'user' => 0, 'value' => 1])); $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPostInterval', 'user' => 0, 'value' => 60))); + ->rows(['name' => 'commentsPostInterval', 'user' => 0, 'value' => 60])); $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsShowCommentOnly', 'user' => 0, 'value' => 0))); + ->rows(['name' => 'commentsShowCommentOnly', 'user' => 0, 'value' => 0])); /** 修改路由 */ $routingTable = $options->routingTable; @@ -853,27 +853,27 @@ Typecho_Date::setTimezoneOffset($options->timezone); } if (isset($routingTable['comment_page'])) { - $routingTable['comment_page'] = array ( + $routingTable['comment_page'] = [ '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 ( + $commentPage = [ 'url' => '[permalink:string]/comment-page-[commentPage:digital]', 'widget' => 'Widget_Archive', 'action' => 'render', - ); + ]; - $routingTable = array_merge($pre, array('comment_page' => $commentPage), $next); + $routingTable = array_merge($pre, ['comment_page' => $commentPage], $next); } $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); + ->rows(['value' => serialize($routingTable)]) + ->where('name = ?', 'routingTable')); } /** @@ -888,14 +888,14 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 删除无用选项 */ $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')); + ->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'))); + ->rows(['name' => 'frontPage', 'user' => 0, 'value' => 'recent'])); } - + /** * 升级至10.2.27 * @@ -908,31 +908,31 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 增加若干选项 */ $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsAvatar', 'user' => 0, 'value' => 1))); - + ->rows(['name' => 'commentsAvatar', 'user' => 0, 'value' => 1])); + $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsAvatarRating', 'user' => 0, 'value' => 'G'))); - + ->rows(['name' => 'commentsAvatarRating', 'user' => 0, 'value' => 'G'])); + //更新扩展 - if (NULL != $options->attachmentTypes) { + if (null != $options->attachmentTypes) { $attachmentTypes = array_map('trim', explode(';', $options->attachmentTypes)); - $attachmentTypesResult = array(); - + $attachmentTypesResult = []; + 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')); + ->rows(['value' => implode(',', $attachmentTypesResult)]) + ->where('name = ?', 'attachmentTypes')); } } } - + /** * 升级至10.3.8 * @@ -945,9 +945,9 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 删除无用选项 */ $db->query($db->delete('table.options') - ->where('name = ?', 'commentsAvatarSize')); + ->where('name = ?', 'commentsAvatarSize')); } - + /** * 升级至10.5.17 * @@ -958,15 +958,15 @@ Typecho_Date::setTimezoneOffset($options->timezone); */ public static function v0_8r10_5_17($db, $options) { - Typecho_Widget::widget('Widget_Themes_Edit', NULL, 'change=' . $options->theme, false)->action(); + Typecho_Widget::widget('Widget_Themes_Edit', null, 'change=' . $options->theme, false)->action(); } - + /** - * 升级至13.10.18 - * - * @param mixed $db - * @param mixed $options + * 升级至13.10.18 + * + * @param mixed $db + * @param mixed $options * @static * @access public * @return void @@ -975,29 +975,29 @@ Typecho_Date::setTimezoneOffset($options->timezone); { // 增加markdown $db->query($db->insert('table.options') - ->rows(array('name' => 'markdown', 'user' => 0, 'value' => 0))); + ->rows(['name' => 'markdown', 'user' => 0, 'value' => 0])); // 更新原来被搞乱的草稿 $db->query($db->update('table.contents') - ->rows(array( - 'type' => 'post_draft', - 'status' => 'publish' - )) + ->rows([ + 'type' => 'post_draft', + 'status' => 'publish' + ]) ->where('type = ? AND status = ?', 'post', 'draft')); $db->query($db->update('table.contents') - ->rows(array( - 'type' => 'page_draft', - 'status' => 'publish' - )) + ->rows([ + 'type' => 'page_draft', + 'status' => 'publish' + ]) ->where('type = ? AND status = ?', 'page', 'draft')); } /** - * v0_9r13_11_17 - * - * @param mixed $db - * @param mixed $options + * v0_9r13_11_17 + * + * @param mixed $db + * @param mixed $options * @static * @access public * @return void @@ -1007,14 +1007,14 @@ Typecho_Date::setTimezoneOffset($options->timezone); 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))); + ->rows(['name' => 'frontArchive', 'user' => 0, 'value' => 0])); } /** - * v0_9r13_11_24 - * - * @param mixed $db - * @param mixed $options + * v0_9r13_11_24 + * + * @param mixed $db + * @param mixed $options * @static * @access public * @return void @@ -1023,7 +1023,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /* 增加数据表 */ $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); + $prefix = $db->getPrefix(); switch (true) { case false !== strpos($adapterName, 'Mysql'): @@ -1073,149 +1073,14 @@ Typecho_Date::setTimezoneOffset($options->timezone); } $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsMarkdown', 'user' => 0, 'value' => 0))); + ->rows(['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) - { - if (!isset($options->frontArchive)) { - $db->query($db->insert('table.options') - ->rows(array('name' => 'frontArchive', 'user' => 0, 'value' => 0))); - } - } - - /** - * v0_9r13_12_20 - * - * @param mixed $db - * @param mixed $options - * @access public - * @return void - */ - public function v0_9r13_12_20($db, $options) - { - if (!isset($options->commentsWhitelist)) { - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsWhitelist', 'user' => 0, 'value' => 0))); - } - } - - /** - * v0_9r14_2_24 - * - * @param mixed $db - * @param mixed $options - * @access public - * @return void - */ - public function v0_9r14_2_24($db, $options) - { - /** 修改数据库字段 */ - $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); - - switch (true) { - case false !== strpos($adapterName, 'Mysql'): - $db->query('ALTER TABLE `' . $prefix . 'metas` ADD `parent` INT(10) UNSIGNED NULL DEFAULT \'0\'', Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'Pgsql'): - $db->query('ALTER TABLE "' . $prefix . 'metas" ADD COLUMN "parent" INT NULL DEFAULT \'0\'', Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'SQLite'): - $uuid = uniqid(); - $db->query('CREATE TABLE ' . $prefix . 'metas' . $uuid . ' ( "mid" INTEGER NOT NULL PRIMARY KEY, - "name" varchar(150) default NULL , - "slug" varchar(150) default NULL , - "type" varchar(32) NOT NULL , - "description" varchar(150) default NULL , - "count" int(10) default \'0\' , - "order" int(10) default \'0\' , - "parent" int(10) default \'0\')', Typecho_Db::WRITE); - $db->query('INSERT INTO ' . $prefix . 'metas' . $uuid . ' ("mid", "name", "slug", "type", "description", "count", "order") - SELECT "mid", "name", "slug", "type", "description", "count", "order" 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(150) default NULL , - "slug" varchar(150) default NULL , - "type" varchar(32) NOT NULL , - "description" varchar(150) default NULL , - "count" int(10) default \'0\' , - "order" int(10) default \'0\' , - "parent" 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); - $db->flushPool(); - break; - - default: - break; - } - } - - /** - * v0_9r14_3_14 + * 升级至17.4.24 * * @param mixed $db * @param mixed $options - * @access public - * @return void - */ - public function v0_9r14_3_14($db, $options) - { - if (!isset($options->secret)) { - $db->query($db->insert('table.options') - ->rows(array('name' => 'secret', 'user' => 0, 'value' => Typecho_Common::randString(32, true)))); - } - } - - /** - * v1_0r14_9_2 - * - * @param mixed $db - * @param mixed $options - * @access public - * @return void - */ - public function v1_0r14_9_2($db, $options) - { - if (!isset($options->lang)) { - $db->query($db->insert('table.options') - ->rows(array('name' => 'lang', 'user' => 0, 'value' => 'zh_CN'))); - } - } - - /** - * v1_0r14_10_10 - * - * @param mixed $db - * @param mixed $options - * @access public - * @return void - */ - public function v1_0r14_10_10($db, $options) - { - if (!isset($options->commentsAntiSpam)) { - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsAntiSpam', 'user' => 0, 'value' => 1))); - } - } - - /** - * 升级至17.4.24 - * - * @param mixed $db - * @param mixed $options * @static * @access public * @return void @@ -1225,7 +1090,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); // 增加markdown if (!isset($options->xmlrpcMarkdown)) { $db->query($db->insert('table.options') - ->rows(array('name' => 'xmlrpcMarkdown', 'user' => 0, 'value' => 0))); + ->rows(['name' => 'xmlrpcMarkdown', 'user' => 0, 'value' => 0])); } } @@ -1243,7 +1108,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); // 增加installed if (!isset($options->installed)) { $db->query($db->insert('table.options') - ->rows(array('name' => 'installed', 'user' => 0, 'value' => 1))); + ->rows(['name' => 'installed', 'user' => 0, 'value' => 1])); } } @@ -1261,7 +1126,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); // 增加xmlRpc开关 if (!isset($options->allowXmlRpc)) { $db->query($db->insert('table.options') - ->rows(array('name' => 'allowXmlRpc', 'user' => 0, 'value' => 2))); + ->rows(['name' => 'allowXmlRpc', 'user' => 0, 'value' => 2])); } } @@ -1274,7 +1139,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 修改数据库字段 */ $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); + $prefix = $db->getPrefix(); switch (true) { case false !== strpos($adapterName, 'Mysql'): @@ -1338,7 +1203,7 @@ Typecho_Date::setTimezoneOffset($options->timezone); { /** 修改数据库字段 */ $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); + $prefix = $db->getPrefix(); switch (true) { case false !== strpos($adapterName, 'Mysql'): @@ -1392,5 +1257,140 @@ Typecho_Date::setTimezoneOffset($options->timezone); break; } } + + /** + * v0_9r13_11_24 + * + * @param mixed $db + * @param mixed $options + * @access public + * @return void + */ + public function v0_9r13_12_6($db, $options) + { + if (!isset($options->frontArchive)) { + $db->query($db->insert('table.options') + ->rows(['name' => 'frontArchive', 'user' => 0, 'value' => 0])); + } + } + + /** + * v0_9r13_12_20 + * + * @param mixed $db + * @param mixed $options + * @access public + * @return void + */ + public function v0_9r13_12_20($db, $options) + { + if (!isset($options->commentsWhitelist)) { + $db->query($db->insert('table.options') + ->rows(['name' => 'commentsWhitelist', 'user' => 0, 'value' => 0])); + } + } + + /** + * v0_9r14_2_24 + * + * @param mixed $db + * @param mixed $options + * @access public + * @return void + */ + public function v0_9r14_2_24($db, $options) + { + /** 修改数据库字段 */ + $adapterName = $db->getAdapterName(); + $prefix = $db->getPrefix(); + + switch (true) { + case false !== strpos($adapterName, 'Mysql'): + $db->query('ALTER TABLE `' . $prefix . 'metas` ADD `parent` INT(10) UNSIGNED NULL DEFAULT \'0\'', Typecho_Db::WRITE); + break; + + case false !== strpos($adapterName, 'Pgsql'): + $db->query('ALTER TABLE "' . $prefix . 'metas" ADD COLUMN "parent" INT NULL DEFAULT \'0\'', Typecho_Db::WRITE); + break; + + case false !== strpos($adapterName, 'SQLite'): + $uuid = uniqid(); + $db->query('CREATE TABLE ' . $prefix . 'metas' . $uuid . ' ( "mid" INTEGER NOT NULL PRIMARY KEY, + "name" varchar(150) default NULL , + "slug" varchar(150) default NULL , + "type" varchar(32) NOT NULL , + "description" varchar(150) default NULL , + "count" int(10) default \'0\' , + "order" int(10) default \'0\' , + "parent" int(10) default \'0\')', Typecho_Db::WRITE); + $db->query('INSERT INTO ' . $prefix . 'metas' . $uuid . ' ("mid", "name", "slug", "type", "description", "count", "order") + SELECT "mid", "name", "slug", "type", "description", "count", "order" 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(150) default NULL , + "slug" varchar(150) default NULL , + "type" varchar(32) NOT NULL , + "description" varchar(150) default NULL , + "count" int(10) default \'0\' , + "order" int(10) default \'0\' , + "parent" 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); + $db->flushPool(); + break; + + default: + break; + } + } + + /** + * v0_9r14_3_14 + * + * @param mixed $db + * @param mixed $options + * @access public + * @return void + */ + public function v0_9r14_3_14($db, $options) + { + if (!isset($options->secret)) { + $db->query($db->insert('table.options') + ->rows(['name' => 'secret', 'user' => 0, 'value' => Typecho_Common::randString(32, true)])); + } + } + + /** + * v1_0r14_9_2 + * + * @param mixed $db + * @param mixed $options + * @access public + * @return void + */ + public function v1_0r14_9_2($db, $options) + { + if (!isset($options->lang)) { + $db->query($db->insert('table.options') + ->rows(['name' => 'lang', 'user' => 0, 'value' => 'zh_CN'])); + } + } + + /** + * v1_0r14_10_10 + * + * @param mixed $db + * @param mixed $options + * @access public + * @return void + */ + public function v1_0r14_10_10($db, $options) + { + if (!isset($options->commentsAntiSpam)) { + $db->query($db->insert('table.options') + ->rows(['name' => 'commentsAntiSpam', 'user' => 0, 'value' => 1])); + } + } } diff --git a/var/Widget/Abstract.php b/var/Widget/Abstract.php index 103387e0..b1a46448 100644 --- a/var/Widget/Abstract.php +++ b/var/Widget/Abstract.php @@ -59,7 +59,7 @@ abstract class Widget_Abstract extends Typecho_Widget * @param mixed $response response对象 * @param mixed $params 参数列表 */ - public function __construct($request, $response, $params = NULL) + public function __construct($request, $response, $params = null) { parent::__construct($request, $response, $params); diff --git a/var/Widget/Abstract/Comments.php b/var/Widget/Abstract/Comments.php index 340fbbfc..5397abfa 100644 --- a/var/Widget/Abstract/Comments.php +++ b/var/Widget/Abstract/Comments.php @@ -18,143 +18,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Abstract_Comments extends Widget_Abstract { - /** - * 获取当前内容结构 - * - * @access protected - * @return array - */ - protected function ___parentContent() - { - return $this->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 ? $this->markdown($text) - : $this->autoP($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'); - } - /** * 增加评论 * @@ -165,21 +28,21 @@ class Widget_Abstract_Comments extends Widget_Abstract public function insert(array $comment) { /** 构建插入结构 */ - $insertStruct = array( - 'cid' => $comment['cid'], - 'created' => empty($comment['created']) ? $this->options->time : $comment['created'], - 'author' => !isset($comment['author']) || strlen($comment['author']) === 0 ? NULL : $comment['author'], - 'authorId' => empty($comment['authorId']) ? 0 : $comment['authorId'], - 'ownerId' => empty($comment['ownerId']) ? 0 : $comment['ownerId'], - 'mail' => !isset($comment['mail']) || strlen($comment['mail']) === 0 ? NULL : $comment['mail'], - 'url' => !isset($comment['url']) || strlen($comment['url']) === 0 ? NULL : $comment['url'], - 'ip' => !isset($comment['ip']) || strlen($comment['ip']) === 0 ? $this->request->getIp() : $comment['ip'], - 'agent' => !isset($comment['agent']) || strlen($comment['agent']) === 0 ? $_SERVER["HTTP_USER_AGENT"] : $comment['agent'], - 'text' => !isset($comment['text']) || strlen($comment['text']) === 0 ? NULL : $comment['text'], - 'type' => empty($comment['type']) ? 'comment' : $comment['type'], - 'status' => empty($comment['status']) ? 'approved' : $comment['status'], - 'parent' => empty($comment['parent']) ? 0 : $comment['parent'], - ); + $insertStruct = [ + 'cid' => $comment['cid'], + 'created' => empty($comment['created']) ? $this->options->time : $comment['created'], + 'author' => !isset($comment['author']) || strlen($comment['author']) === 0 ? null : $comment['author'], + 'authorId' => empty($comment['authorId']) ? 0 : $comment['authorId'], + 'ownerId' => empty($comment['ownerId']) ? 0 : $comment['ownerId'], + 'mail' => !isset($comment['mail']) || strlen($comment['mail']) === 0 ? null : $comment['mail'], + 'url' => !isset($comment['url']) || strlen($comment['url']) === 0 ? null : $comment['url'], + 'ip' => !isset($comment['ip']) || strlen($comment['ip']) === 0 ? $this->request->getIp() : $comment['ip'], + 'agent' => !isset($comment['agent']) || strlen($comment['agent']) === 0 ? $_SERVER["HTTP_USER_AGENT"] : $comment['agent'], + 'text' => !isset($comment['text']) || strlen($comment['text']) === 0 ? 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']; @@ -194,11 +57,11 @@ class Widget_Abstract_Comments extends Widget_Abstract $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; + $num = $this->db->fetchObject($this->db->select(['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'])); + $this->db->query($this->db->update('table.contents')->rows(['commentsNum' => $num]) + ->where('cid = ?', $comment['cid'])); return $insertId; } @@ -224,21 +87,21 @@ class Widget_Abstract_Comments extends Widget_Abstract } /** 构建插入结构 */ - $preUpdateStruct = array( - 'author' => !isset($comment['author']) || strlen($comment['author']) === 0 ? NULL : $comment['author'], - 'mail' => !isset($comment['mail']) || strlen($comment['mail']) === 0 ? NULL : $comment['mail'], - 'url' => !isset($comment['url']) || strlen($comment['url']) === 0 ? NULL : $comment['url'], - 'text' => !isset($comment['text']) || strlen($comment['text']) === 0 ? NULL : $comment['text'], - 'status' => empty($comment['status']) ? 'approved' : $comment['status'], - ); + $preUpdateStruct = [ + 'author' => !isset($comment['author']) || strlen($comment['author']) === 0 ? null : $comment['author'], + 'mail' => !isset($comment['mail']) || strlen($comment['mail']) === 0 ? null : $comment['mail'], + 'url' => !isset($comment['url']) || strlen($comment['url']) === 0 ? null : $comment['url'], + 'text' => !isset($comment['text']) || strlen($comment['text']) === 0 ? null : $comment['text'], + 'status' => empty($comment['status']) ? 'approved' : $comment['status'], + ]; - $updateStruct = array(); + $updateStruct = []; foreach ($comment as $key => $val) { if ((array_key_exists($key, $preUpdateStruct))) { $updateStruct[$key] = $preUpdateStruct[$key]; } } - + /** 更新创建时间 */ if (!empty($comment['created'])) { $updateStruct['created'] = $comment['created']; @@ -248,11 +111,11 @@ class Widget_Abstract_Comments extends Widget_Abstract $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; + $num = $this->db->fetchObject($this->db->select(['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)); + $this->db->query($this->db->update('table.contents')->rows(['commentsNum' => $num]) + ->where('cid = ?', $cid)); return $updateRows; } @@ -280,11 +143,11 @@ class Widget_Abstract_Comments extends Widget_Abstract $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; + $num = $this->db->fetchObject($this->db->select(['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)); + $this->db->query($this->db->update('table.contents')->rows(['commentsNum' => $num]) + ->where('cid = ?', $cid)); return $deleteRows; } @@ -296,7 +159,7 @@ class Widget_Abstract_Comments extends Widget_Abstract * @param Typecho_Db_Query $condition 条件 * @return mixed */ - public function commentIsWriteable(Typecho_Db_Query $condition = NULL) + public function commentIsWriteable(Typecho_Db_Query $condition = null) { if (empty($condition)) { if ($this->have() && ($this->user->pass('editor', true) || $this->ownerId == $this->user->uid)) { @@ -322,7 +185,20 @@ class Widget_Abstract_Comments extends Widget_Abstract */ public function size(Typecho_Db_Query $condition) { - return $this->db->fetchObject($condition->select(array('COUNT(coid)' => 'num'))->from('table.comments'))->num; + return $this->db->fetchObject($condition->select(['COUNT(coid)' => 'num'])->from('table.comments'))->num; + } + + /** + * 将每行的值压入堆栈 + * + * @access public + * @param array $value 每行的值 + * @return array + */ + public function push(array $value) + { + $value = $this->filter($value); + return parent::push($value); } /** @@ -339,19 +215,6 @@ class Widget_Abstract_Comments extends Widget_Abstract return $value; } - /** - * 将每行的值压入堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function push(array $value) - { - $value = $this->filter($value); - return parent::push($value); - } - /** * 输出文章发布日期 * @@ -359,7 +222,7 @@ class Widget_Abstract_Comments extends Widget_Abstract * @param string $format 日期格式 * @return void */ - public function date($format = NULL) + public function date($format = null) { echo $this->date->format(empty($format) ? $this->options->commentDateFormat : $format); } @@ -372,13 +235,13 @@ class Widget_Abstract_Comments extends Widget_Abstract * @param boolean $noFollow 是否加上nofollow标签 * @return void */ - public function author($autoLink = NULL, $noFollow = NULL) + public function author($autoLink = null, $noFollow = null) { - $autoLink = (NULL === $autoLink) ? $this->options->commentsShowUrl : $autoLink; - $noFollow = (NULL === $noFollow) ? $this->options->commentsUrlNofollow : $noFollow; + $autoLink = (null === $autoLink) ? $this->options->commentsShowUrl : $autoLink; + $noFollow = (null === $noFollow) ? $this->options->commentsUrlNofollow : $noFollow; if ($this->url && $autoLink) { - echo '' , $this->author , ''; + echo '', $this->author, ''; } else { echo $this->author; } @@ -392,16 +255,16 @@ class Widget_Abstract_Comments extends Widget_Abstract * @param string $default 默认输出头像 * @return void */ - public function gravatar($size = 32, $default = NULL) + 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) { $url = Typecho_Common::gravatarUrl($this->mail, $size, $rating, $default, $this->request->isSecure()); echo '' .
-                $this->author . ''; + $this->author . '" width="' . $size . '" height="' . $size . '" />'; } } } @@ -420,9 +283,142 @@ class Widget_Abstract_Comments extends Widget_Abstract } /** - * autoP - * - * @param mixed $text + * 获取当前内容结构 + * + * @access protected + * @return array + */ + protected function ___parentContent() + { + return $this->db->fetchRow($this->widget('Widget_Abstract_Contents')->select() + ->where('table.contents.cid = ?', $this->cid) + ->limit(1), [$this->widget('Widget_Abstract_Contents'), 'filter']); + } + + /** + * 获取查询对象 + * + * @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 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 = []; + $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 = ['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 ? $this->markdown($text) + : $this->autoP($text); + } + + $text = $this->pluginHandle(__CLASS__)->contentEx($text, $this); + return Typecho_Common::stripTags($text, '


' . $this->options->commentsHTMLTagAllowed); + } + + /** + * markdown + * + * @param mixed $text + * @access public + * @return string + */ + public function markdown($text) + { + $html = $this->pluginHandle(__CLASS__)->trigger($parsed)->markdown($text); + + if (!$parsed) { + $html = Markdown::convert($text); + } + + return $html; + } + + /** + * autoP + * + * @param mixed $text * @access public * @return string */ @@ -444,21 +440,25 @@ class Widget_Abstract_Comments extends Widget_Abstract } /** - * markdown - * - * @param mixed $text - * @access public + * 输出词义化日期 + * + * @access protected * @return string */ - public function markdown($text) + protected function ___dateWord() { - $html = $this->pluginHandle(__CLASS__)->trigger($parsed)->markdown($text); + return $this->date->word(); + } - if (!$parsed) { - $html = Markdown::convert($text); - } - - return $html; + /** + * 锚点id + * + * @access protected + * @return string + */ + protected function ___theId() + { + return $this->type . '-' . $this->coid; } } diff --git a/var/Widget/Abstract/Contents.php b/var/Widget/Abstract/Contents.php index 391c1e6f..3ee16ffe 100644 --- a/var/Widget/Abstract/Contents.php +++ b/var/Widget/Abstract/Contents.php @@ -15,238 +15,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Abstract_Contents extends Widget_Abstract { - /** - * 将tags取出 - * - * @access protected - * @return array - */ - protected function ___tags() - { - 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')); - } - - /** - * 文章作者 - * - * @access protected - * @return Typecho_Config - */ - protected function ___author() - { - return $this->widget('Widget_Users_Author@' . $this->cid, array('uid' => $this->authorId)); - } - - /** - * 获取词义化日期 - * - * @access protected - * @return string - */ - protected function ___dateWord() - { - return $this->date->word(); - } - - /** - * 获取父id - * - * @access protected - * @return string - */ - 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 Typecho_Config - */ - 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 ? $this->markdown($content) - : $this->autoP($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 ? $this->markdown($content) - : $this->autoP($content); - } - - return $this->pluginHandle(__CLASS__)->contentEx($content, $this); - } - - /** - * 输出文章的第一行作为摘要 - * - * @return string - */ - protected function ___summary() - { - $content = $this->content; - $parts = preg_split("/(<\/\s*(?:p|blockquote|q|pre|table)\s*>)/i", $content, 2, PREG_SPLIT_DELIM_CAPTURE); - if (!empty($parts)) { - $content = $parts[0] . $parts[1]; - } - - return $content; - } - - /** - * 锚点id - * - * @access protected - * @return string - */ - protected function ___theId() - { - return $this->type . '-' . $this->cid; - } - - /** - * 回复框id - * - * @access protected - * @return string - */ - protected function ___respondId() - { - return 'respond-' . $this->theId; - } - - /** - * 评论地址 - * - * @access protected - * @return string - */ - protected function ___commentUrl() - { - /** 生成反馈地址 */ - /** 评论 */ - return Typecho_Router::url('feedback', - array('type' => 'comment', 'permalink' => $this->pathinfo), $this->options->index); - } - - /** - * trackback地址 - * - * @access protected - * @return string - */ - protected function ___trackbackUrl() - { - return Typecho_Router::url('feedback', - array('type' => 'trackback', 'permalink' => $this->pathinfo), $this->options->index); - } - - /** - * 回复地址 - * - * @access protected - * @return string - */ - 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 = ? OR (table.contents.type = ? AND table.contents.parent = ?)", - $type, $type . '_draft', 0); - - 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); - } - /** * 获取查询对象 * @@ -256,9 +24,9 @@ class Widget_Abstract_Contents extends Widget_Abstract 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'); + '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'); } /** @@ -271,23 +39,23 @@ class Widget_Abstract_Contents extends Widget_Abstract public function insert(array $content) { /** 构建插入结构 */ - $insertStruct = array( - 'title' => !isset($content['title']) || strlen($content['title']) === 0 ? NULL : htmlspecialchars($content['title']), - 'created' => !isset($content['created']) ? $this->options->time : $content['created'], - 'modified' => $this->options->time, - 'text' => !isset($content['text']) || strlen($content['text']) === 0 ? 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' => !isset($content['password']) || strlen($content['password']) === 0 ? 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']) - ); + $insertStruct = [ + 'title' => !isset($content['title']) || strlen($content['title']) === 0 ? null : htmlspecialchars($content['title']), + 'created' => !isset($content['created']) ? $this->options->time : $content['created'], + 'modified' => $this->options->time, + 'text' => !isset($content['text']) || strlen($content['text']) === 0 ? 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' => !isset($content['password']) || strlen($content['password']) === 0 ? 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']; @@ -298,12 +66,54 @@ class Widget_Abstract_Contents extends Widget_Abstract /** 更新缩略名 */ if ($insertId > 0) { - $this->applySlug(!isset($content['slug']) || strlen($content['slug']) === 0 ? NULL : $content['slug'], $insertId); + $this->applySlug(!isset($content['slug']) || strlen($content['slug']) === 0 ? null : $content['slug'], $insertId); } return $insertId; } + /** + * 为内容应用缩略名 + * + * @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(['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(['slug' => $result]) + ->where('cid = ?', $cid)); + + return $result; + } + /** * 更新内容 * @@ -320,21 +130,21 @@ class Widget_Abstract_Contents extends Widget_Abstract } /** 构建更新结构 */ - $preUpdateStruct = array( - 'title' => !isset($content['title']) || strlen($content['title']) === 0 ? NULL : htmlspecialchars($content['title']), - 'order' => empty($content['order']) ? 0 : intval($content['order']), - 'text' => !isset($content['text']) || strlen($content['text']) === 0 ? 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']) - ); + $preUpdateStruct = [ + 'title' => !isset($content['title']) || strlen($content['title']) === 0 ? null : htmlspecialchars($content['title']), + 'order' => empty($content['order']) ? 0 : intval($content['order']), + 'text' => !isset($content['text']) || strlen($content['text']) === 0 ? 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(); + $updateStruct = []; foreach ($content as $key => $val) { if (array_key_exists($key, $preUpdateStruct)) { $updateStruct[$key] = $preUpdateStruct[$key]; @@ -354,224 +164,12 @@ class Widget_Abstract_Contents extends Widget_Abstract /** 更新缩略名 */ if ($updateRows > 0 && isset($content['slug'])) { - $this->applySlug(!isset($content['slug']) || strlen($content['slug']) === 0 ? NULL : $content['slug'], $updateCondition); + $this->applySlug(!isset($content['slug']) || strlen($content['slug']) === 0 ? null : $content['slug'], $updateCondition); } 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.fields') - ->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)); - } - } - /** * 内容是否可以被修改 * @@ -585,6 +183,176 @@ class Widget_Abstract_Contents extends Widget_Abstract return $post && ($this->user->pass('editor', true) || $post['authorId'] == $this->user->uid); } + /** + * 删除内容 + * + * @access public + * @param Typecho_Db_Query $condition 查询对象 + * @return integer + */ + public function delete(Typecho_Db_Query $condition) + { + return $this->db->query($condition->delete('table.contents')); + } + + /** + * 删除自定义字段 + * + * @param integer $cid + * @access public + * @return integer + */ + public function deleteFields($cid) + { + return $this->db->query($this->db->delete('table.fields') + ->where('cid = ?', $cid)); + } + + /** + * 保存自定义字段 + * + * @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]; + } elseif (strpos($name, ':') > 0) { + [$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 + * @access public + * @return boolean + */ + public function checkFieldName($name) + { + return preg_match("/^[_a-z][_a-z0-9]*$/i", $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, ['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([ + '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([ + '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([ + 'cid' => $cid, + 'name' => $name, + 'type' => 'int', + 'str_value' => null, + 'int_value' => $value, + 'float_value' => 0 + ])); + } else { + $struct = [ + '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)); + } + } + /** * 按照条件计算内容数量 * @@ -595,11 +363,11 @@ class Widget_Abstract_Contents extends Widget_Abstract public function size(Typecho_Db_Query $condition) { return $this->db->fetchObject($condition - ->select(array('COUNT(DISTINCT table.contents.cid)' => 'num')) + ->select(['COUNT(DISTINCT table.contents.cid)' => 'num']) ->from('table.contents') ->cleanAttribute('group'))->num; } - + /** * 获取当前所有自定义模板 * @@ -609,7 +377,7 @@ class Widget_Abstract_Contents extends Widget_Abstract public function getTemplates() { $files = glob($this->options->themeFile($this->options->theme, '*.php')); - $result = array(); + $result = []; foreach ($files as $file) { $info = Typecho_Plugin::parseInfo($file); @@ -623,6 +391,19 @@ class Widget_Abstract_Contents extends Widget_Abstract return $result; } + /** + * 将每行的值压入堆栈 + * + * @access public + * @param array $value 每行的值 + * @return array + */ + public function push(array $value) + { + $value = $this->filter($value); + return parent::push($value); + } + /** * 通用过滤器 * @@ -638,10 +419,10 @@ class Widget_Abstract_Contents extends Widget_Abstract ->select()->from('table.metas') ->join('table.relationships', 'table.relationships.mid = table.metas.mid') ->where('table.relationships.cid = ?', $value['cid']) - ->where('table.metas.type = ?', 'category'), array($this->widget('Widget_Metas_Category_List'), 'filter')); + ->where('table.metas.type = ?', 'category'), [$this->widget('Widget_Metas_Category_List'), 'filter']); - $value['category'] = NULL; - $value['directory'] = array(); + $value['category'] = null; + $value['directory'] = []; /** 取出第一个分类作为slug条件 */ if (!empty($value['categories'])) { @@ -652,7 +433,7 @@ class Widget_Abstract_Contents extends Widget_Abstract $field = 'mid'; } - return $a[$field] < $b[$field] ? -1 : 1; + return $a[$field] < $b[$field] ? - 1 : 1; }); $value['category'] = $value['categories'][0]['slug']; @@ -673,7 +454,7 @@ class Widget_Abstract_Contents extends Widget_Abstract /** 获取路由类型并判断此类型在路由表中是否存在 */ $type = $value['type']; - $routeExists = (NULL != Typecho_Router::get($type)); + $routeExists = (null != Typecho_Router::get($type)); $tmpSlug = $value['slug']; $tmpCategory = $value['category']; @@ -694,15 +475,15 @@ class Widget_Abstract_Contents extends Widget_Abstract //增加数据信息 $value['attachment'] = new Typecho_Config($content); - $value['attachment']->isImage = in_array($content['type'], array('jpg', 'jpeg', 'gif', 'png', 'tiff', 'bmp')); + $value['attachment']->isImage = in_array($content['type'], ['jpg', 'jpeg', 'gif', 'png', 'tiff', 'bmp']); $value['attachment']->url = Widget_Upload::attachmentHandle($value); if ($value['attachment']->isImage) { $value['text'] = '' .
-                $value['title'] . ''; + $value['title'] . '" />'; } else { $value['text'] = '' . $value['title'] . ''; + $value['title'] . '">' . $value['title'] . ''; } } @@ -730,9 +511,9 @@ class Widget_Abstract_Contents extends Widget_Abstract /** 处理密码保护流程 */ if (strlen($value['password']) > 0 && - $value['password'] !== Typecho_Cookie::get('protectPassword_' . $value['cid']) && - $value['authorId'] != $this->user->uid && - !$this->user->pass('editor', true)) { + $value['password'] !== Typecho_Cookie::get('protectPassword_' . $value['cid']) && + $value['authorId'] != $this->user->uid && + !$this->user->pass('editor', true)) { $value['hidden'] = true; } @@ -742,40 +523,27 @@ class Widget_Abstract_Contents extends Widget_Abstract if ($value['hidden']) { $value['text'] = '

' . - '

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

' . - '

+ '

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

' . + '

' . - '
'; + ''; $value['title'] = _t('此内容被密码保护'); - $value['tags'] = array(); + $value['tags'] = []; $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 日期格式 */ - public function date($format = NULL) + public function date($format = null) { echo $this->date->format(empty($format) ? $this->options->postDateFormat : $format); } @@ -789,7 +557,7 @@ class Widget_Abstract_Contents extends Widget_Abstract public function content($more = false) { echo false !== $more && false !== strpos($this->text, '') ? - $this->excerpt . "

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

" : $this->content; + $this->excerpt . "

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

" : $this->content; } /** @@ -856,7 +624,7 @@ class Widget_Abstract_Contents extends Widget_Abstract } else { /** 对自动关闭反馈功能的支持 */ if (('ping' == $permission || 'comment' == $permission) && $this->options->commentsPostTimeout > 0 && - $this->options->commentsAutoClose) { + $this->options->commentsAutoClose) { if ($this->options->time - $this->created > $this->options->commentsPostTimeout) { return false; } @@ -878,15 +646,15 @@ class Widget_Abstract_Contents extends Widget_Abstract * @param string $default 如果没有则输出 * @return void */ - public function category($split = ',', $link = true, $default = NULL) + public function category($split = ',', $link = true, $default = null) { $categories = $this->categories; if ($categories) { - $result = array(); + $result = []; foreach ($categories as $category) { $result[] = $link ? '' - . $category['name'] . '' : $category['name']; + . $category['name'] . '' : $category['name']; } echo implode($split, $result); @@ -904,18 +672,18 @@ class Widget_Abstract_Contents extends Widget_Abstract * @param string $default 如果没有则输出 * @return void */ - public function directory($split = '/', $link = true, $default = NULL) + public function directory($split = '/', $link = true, $default = null) { $category = $this->categories[0]; $directory = $this->widget('Widget_Metas_Category_List')->getAllParents($category['mid']); $directory[] = $category; if ($directory) { - $result = array(); + $result = []; foreach ($directory as $category) { $result[] = $link ? '' - . $category['name'] . '' : $category['name']; + . $category['name'] . '' : $category['name']; } echo implode($split, $result); @@ -933,14 +701,14 @@ class Widget_Abstract_Contents extends Widget_Abstract * @param string $default 如果没有则输出 * @return void */ - public function tags($split = ',', $link = true, $default = NULL) + public function tags($split = ',', $link = true, $default = null) { /** 取出tags */ if ($this->tags) { - $result = array(); + $result = []; foreach ($this->tags as $tag) { $result[] = $link ? '' - . $tag['name'] . '' : $tag['name']; + . $tag['name'] . '' : $tag['name']; } echo implode($split, $result); @@ -962,9 +730,131 @@ class Widget_Abstract_Contents extends Widget_Abstract } /** - * autoP - * - * @param mixed $text + * 将tags取出 + * + * @access protected + * @return array + */ + protected function ___tags() + { + 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'), [$this->widget('Widget_Abstract_Metas'), 'filter']); + } + + /** + * 文章作者 + * + * @access protected + * @return Typecho_Config + */ + protected function ___author() + { + return $this->widget('Widget_Users_Author@' . $this->cid, ['uid' => $this->authorId]); + } + + /** + * 获取词义化日期 + * + * @access protected + * @return string + */ + protected function ___dateWord() + { + return $this->date->word(); + } + + /** + * 获取父id + * + * @access protected + * @return string + */ + 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 Typecho_Config + */ + protected function ___fields() + { + $fields = []; + $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 ? $this->markdown($content) + : $this->autoP($content); + } + + $contents = explode('', $content); + [$excerpt] = $contents; + + return Typecho_Common::fixHtml($this->pluginHandle(__CLASS__)->excerptEx($excerpt, $this)); + } + + /** + * markdown + * + * @param mixed $text + * @access public + * @return string + */ + public function markdown($text) + { + $html = $this->pluginHandle(__CLASS__)->trigger($parsed)->markdown($text); + + if (!$parsed) { + $html = Markdown::convert($text); + } + + return $html; + } + + /** + * autoP + * + * @param mixed $text * @access public * @return string */ @@ -986,21 +876,131 @@ class Widget_Abstract_Contents extends Widget_Abstract } /** - * markdown - * - * @param mixed $text - * @access public + * 获取文章内容 + * + * @access protected * @return string */ - public function markdown($text) + protected function ___content() { - $html = $this->pluginHandle(__CLASS__)->trigger($parsed)->markdown($text); - - if (!$parsed) { - $html = Markdown::convert($text); + if ($this->hidden) { + return $this->text; } - return $html; + $content = $this->pluginHandle(__CLASS__)->trigger($plugged)->content($this->text, $this); + + if (!$plugged) { + $content = $this->isMarkdown ? $this->markdown($content) + : $this->autoP($content); + } + + return $this->pluginHandle(__CLASS__)->contentEx($content, $this); + } + + /** + * 输出文章的第一行作为摘要 + * + * @return string + */ + protected function ___summary() + { + $content = $this->content; + $parts = preg_split("/(<\/\s*(?:p|blockquote|q|pre|table)\s*>)/i", $content, 2, PREG_SPLIT_DELIM_CAPTURE); + if (!empty($parts)) { + $content = $parts[0] . $parts[1]; + } + + return $content; + } + + /** + * 锚点id + * + * @access protected + * @return string + */ + protected function ___theId() + { + return $this->type . '-' . $this->cid; + } + + /** + * 回复框id + * + * @access protected + * @return string + */ + protected function ___respondId() + { + return 'respond-' . $this->theId; + } + + /** + * 评论地址 + * + * @access protected + * @return string + */ + protected function ___commentUrl() + { + /** 生成反馈地址 */ + /** 评论 */ + return Typecho_Router::url('feedback', + ['type' => 'comment', 'permalink' => $this->pathinfo], $this->options->index); + } + + /** + * trackback地址 + * + * @access protected + * @return string + */ + protected function ___trackbackUrl() + { + return Typecho_Router::url('feedback', + ['type' => 'trackback', 'permalink' => $this->pathinfo], $this->options->index); + } + + /** + * 回复地址 + * + * @access protected + * @return string + */ + 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(['COUNT(table.contents.cid)' => 'num'])->from('table.contents') + ->where("table.contents.{$column} > {$offset}") + ->where("table.contents.type = ? OR (table.contents.type = ? AND table.contents.parent = ?)", + $type, $type . '_draft', 0); + + 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); } } diff --git a/var/Widget/Abstract/Metas.php b/var/Widget/Abstract/Metas.php index 08a9256b..41beca7c 100644 --- a/var/Widget/Abstract/Metas.php +++ b/var/Widget/Abstract/Metas.php @@ -20,65 +20,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Abstract_Metas extends Widget_Abstract { - /** - * 锚点id - * - * @access protected - * @return string - */ - protected function ___theId() - { - return $this->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')); - } - /** * 获取记录总数 * @@ -88,7 +29,20 @@ class Widget_Abstract_Metas extends Widget_Abstract */ public function size(Typecho_Db_Query $condition) { - return $this->db->fetchObject($condition->select(array('COUNT(mid)' => 'num'))->from('table.metas'))->num; + return $this->db->fetchObject($condition->select(['COUNT(mid)' => 'num'])->from('table.metas'))->num; + } + + /** + * 将每行的值压入堆栈 + * + * @access public + * @param array $value 每行的值 + * @return array + */ + public function push(array $value) + { + $value = $this->filter($value); + return parent::push($value); } /** @@ -102,7 +56,7 @@ class Widget_Abstract_Metas extends Widget_Abstract { //生成静态链接 $type = $value['type']; - $routeExists = (NULL != Typecho_Router::get($type)); + $routeExists = (null != Typecho_Router::get($type)); $tmpSlug = $value['slug']; $value['slug'] = urlencode($value['slug']); @@ -123,32 +77,19 @@ class Widget_Abstract_Metas extends Widget_Abstract return $value; } - /** - * 将每行的值压入堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function push(array $value) - { - $value = $this->filter($value); - return parent::push($value); - } - /** * 获取最大排序 - * - * @param mixed $type - * @param int $parent + * + * @param mixed $type + * @param int $parent * @access public * @return integer */ public function getMaxOrder($type, $parent = 0) { - return $this->db->fetchObject($this->db->select(array('MAX(order)' => 'maxOrder')) - ->from('table.metas') - ->where('type = ? AND parent = ?', 'category', $parent))->maxOrder; + return $this->db->fetchObject($this->db->select(['MAX(order)' => 'maxOrder']) + ->from('table.metas') + ->where('type = ? AND parent = ?', 'category', $parent))->maxOrder; } /** @@ -162,11 +103,24 @@ class Widget_Abstract_Metas extends Widget_Abstract 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)); + $this->update(['order' => $sort + 1], + $this->db->sql()->where('mid = ?', $mid)->where('type = ?', $type)); } } + /** + * 更新记录 + * + * @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)); + } + /** * 合并数据 * @@ -179,14 +133,14 @@ class Widget_Abstract_Metas extends Widget_Abstract public function merge($mid, $type, array $metas) { $contents = Typecho_Common::arrayFlatten($this->db->fetchAll($this->select('cid') - ->from('table.relationships') - ->where('mid = ?', $mid)), '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'); + ->select('cid')->from('table.relationships') + ->where('mid = ?', $meta)), 'cid'); $where = $this->db->sql()->where('mid = ? AND type = ?', $meta, $type); $this->delete($where); @@ -195,20 +149,43 @@ class Widget_Abstract_Metas extends Widget_Abstract foreach ($diffContents as $content) { $this->db->query($this->db->insert('table.relationships') - ->rows(array('mid' => $mid, 'cid' => $content))); + ->rows(['mid' => $mid, 'cid' => $content])); $contents[] = $content; } - $this->update(array('parent' => $mid), $this->db->sql()->where('parent = ?', $meta)); + $this->update(['parent' => $mid], $this->db->sql()->where('parent = ?', $meta)); unset($existsContents); } } $num = $this->db->fetchObject($this->db - ->select(array('COUNT(mid)' => 'num'))->from('table.relationships') - ->where('table.relationships.mid = ?', $mid))->num; + ->select(['COUNT(mid)' => 'num'])->from('table.relationships') + ->where('table.relationships.mid = ?', $mid))->num; - $this->update(array('count' => $num), $this->db->sql()->where('mid = ?', $mid)); + $this->update(['count' => $num], $this->db->sql()->where('mid = ?', $mid)); + } + + /** + * 获取原始查询对象 + * + * @access public + * @return Typecho_Db_Query + */ + public function select() + { + return $this->db->select()->from('table.metas'); + } + + /** + * 删除记录 + * + * @access public + * @param Typecho_Db_Query $condition 删除条件 + * @return integer + */ + public function delete(Typecho_Db_Query $condition) + { + return $this->db->query($condition->delete('table.metas')); } /** @@ -220,8 +197,8 @@ class Widget_Abstract_Metas extends Widget_Abstract */ public function scanTags($inputTags) { - $tags = is_array($inputTags) ? $inputTags : array($inputTags); - $result = array(); + $tags = is_array($inputTags) ? $inputTags : [$inputTags]; + $result = []; foreach ($tags as $tag) { if (empty($tag)) { @@ -229,8 +206,8 @@ class Widget_Abstract_Metas extends Widget_Abstract } $row = $this->db->fetchRow($this->select() - ->where('type = ?', 'tag') - ->where('name = ?', $tag)->limit(1)); + ->where('type = ?', 'tag') + ->where('name = ?', $tag)->limit(1)); if ($row) { $result[] = $row['mid']; @@ -238,13 +215,13 @@ class Widget_Abstract_Metas extends Widget_Abstract $slug = Typecho_Common::slugName($tag); if ($slug) { - $result[] = $this->insert(array( - 'name' => $tag, - 'slug' => $slug, - 'type' => 'tag', - 'count' => 0, - 'order' => 0, - )); + $result[] = $this->insert([ + 'name' => $tag, + 'slug' => $slug, + 'type' => 'tag', + 'count' => 0, + 'order' => 0, + ]); } } } @@ -252,9 +229,21 @@ class Widget_Abstract_Metas extends Widget_Abstract return is_array($inputTags) ? $result : current($result); } + /** + * 插入一条记录 + * + * @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 * @return void */ @@ -288,13 +277,24 @@ class Widget_Abstract_Metas extends Widget_Abstract */ 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; + $num = $this->db->fetchObject($this->db->select(['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)); + $this->db->query($this->db->update('table.metas')->rows(['count' => $num]) + ->where('mid = ?', $mid)); + } + + /** + * 锚点id + * + * @access protected + * @return string + */ + protected function ___theId() + { + return $this->type . '-' . $this->mid; } } diff --git a/var/Widget/Abstract/Options.php b/var/Widget/Abstract/Options.php index 1b8a7996..b9d9fe83 100644 --- a/var/Widget/Abstract/Options.php +++ b/var/Widget/Abstract/Options.php @@ -20,19 +20,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Abstract_Options extends Widget_Abstract { - /** - * 以checkbox选项判断是否某个值被启用 - * - * @access protected - * @param mixed $settings 选项集合 - * @param string $name 选项名称 - * @return integer - */ - protected function isEnableByCheckbox($settings, $name) - { - return is_array($settings) && in_array($name, $settings) ? 1 : 0; - } - /** * 获取原始查询对象 * @@ -90,6 +77,19 @@ class Widget_Abstract_Options extends Widget_Abstract */ public function size(Typecho_Db_Query $condition) { - return $this->db->fetchObject($condition->select(array('COUNT(name)' => 'num'))->from('table.options'))->num; + return $this->db->fetchObject($condition->select(['COUNT(name)' => 'num'])->from('table.options'))->num; + } + + /** + * 以checkbox选项判断是否某个值被启用 + * + * @access protected + * @param mixed $settings 选项集合 + * @param string $name 选项名称 + * @return integer + */ + protected function isEnableByCheckbox($settings, $name) + { + return is_array($settings) && in_array($name, $settings) ? 1 : 0; } } diff --git a/var/Widget/Abstract/Users.php b/var/Widget/Abstract/Users.php index 464c834d..fe70769a 100644 --- a/var/Widget/Abstract/Users.php +++ b/var/Widget/Abstract/Users.php @@ -20,24 +20,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Abstract_Users extends Widget_Abstract { - /** - * ___options - * - * @access protected - * @return Typecho_Config - */ - protected function ___options() - { - $rows = $this->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); - } - /** * 判断用户名称是否存在 * @@ -48,9 +30,9 @@ class Widget_Abstract_Users extends Widget_Abstract public function nameExists($name) { $select = $this->db->select() - ->from('table.users') - ->where('name = ?', $name) - ->limit(1); + ->from('table.users') + ->where('name = ?', $name) + ->limit(1); if ($this->request->uid) { $select->where('uid <> ?', $this->request->uid); @@ -70,9 +52,9 @@ class Widget_Abstract_Users extends Widget_Abstract public function mailExists($mail) { $select = $this->db->select() - ->from('table.users') - ->where('mail = ?', $mail) - ->limit(1); + ->from('table.users') + ->where('mail = ?', $mail) + ->limit(1); if ($this->request->uid) { $select->where('uid <> ?', $this->request->uid); @@ -92,9 +74,9 @@ class Widget_Abstract_Users extends Widget_Abstract public function screenNameExists($screenName) { $select = $this->db->select() - ->from('table.users') - ->where('screenName = ?', $screenName) - ->limit(1); + ->from('table.users') + ->where('screenName = ?', $screenName) + ->limit(1); if ($this->request->uid) { $select->where('uid <> ?', $this->request->uid); @@ -105,26 +87,16 @@ class Widget_Abstract_Users extends Widget_Abstract } /** - * 获取页面偏移 + * 将每行的值压入堆栈 * - * @access protected - * @param string $column 字段名 - * @param integer $offset 偏移值 - * @param string $group 用户组 - * @param integer $pageSize 分页值 - * @return integer + * @access public + * @param array $value 每行的值 + * @return array */ - protected function getPageOffset($column, $offset, $group = NULL, $pageSize = 20) + public function push(array $value) { - $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); + $value = $this->filter($value); + return parent::push($value); } /** @@ -137,7 +109,7 @@ class Widget_Abstract_Users extends Widget_Abstract public function filter(array $value) { //生成静态链接 - $routeExists = (NULL != Typecho_Router::get('author')); + $routeExists = (null != Typecho_Router::get('author')); $value['permalink'] = $routeExists ? Typecho_Router::url('author', $value, $this->options->index) : '#'; @@ -155,19 +127,6 @@ class Widget_Abstract_Users extends Widget_Abstract return $value; } - /** - * 将每行的值压入堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function push(array $value) - { - $value = $this->filter($value); - return parent::push($value); - } - /** * 查询方法 * @@ -188,7 +147,7 @@ class Widget_Abstract_Users extends Widget_Abstract */ public function size(Typecho_Db_Query $condition) { - return $this->db->fetchObject($condition->select(array('COUNT(uid)' => 'num'))->from('table.users'))->num; + return $this->db->fetchObject($condition->select(['COUNT(uid)' => 'num'])->from('table.users'))->num; } /** @@ -238,10 +197,51 @@ class Widget_Abstract_Users extends Widget_Abstract * @param string $class 默认css class * @return void */ - public function gravatar($size = 40, $rating = 'X', $default = NULL, $class = NULL) + public function gravatar($size = 40, $rating = 'X', $default = null, $class = null) { $url = Typecho_Common::gravatarUrl($this->mail, $size, $rating, $default, $this->request->isSecure()); echo ''; + $this->screenName . '" width="' . $size . '" height="' . $size . '" />'; + } + + /** + * ___options + * + * @access protected + * @return Typecho_Config + */ + protected function ___options() + { + $rows = $this->db->fetchAll($this->db->select() + ->from('table.options')->where('user = ?', $this->uid)); + $options = []; + foreach ($rows as $row) { + $options[$row['name']] = $row['value']; + } + + return new Typecho_Config($options); + } + + /** + * 获取页面偏移 + * + * @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(['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); } } diff --git a/var/Widget/Ajax.php b/var/Widget/Ajax.php index 3825c39c..7011959d 100644 --- a/var/Widget/Ajax.php +++ b/var/Widget/Ajax.php @@ -44,7 +44,7 @@ class Widget_Ajax extends Widget_Abstract_Options implements Widget_Interface_Do if ($client) { $client->setHeader('User-Agent', $this->options->generator) ->setTimeout(10); - $result = array('available' => 0); + $result = ['available' => 0]; try { $client->send('http://typecho.org/version.json'); @@ -54,7 +54,7 @@ class Widget_Ajax extends Widget_Abstract_Options implements Widget_Interface_Do $json = Json::decode($response, true); if (!empty($json)) { - list($soft, $version) = explode(' ', $this->options->generator); + [$soft, $version] = explode(' ', $this->options->generator); $current = explode('/', $version); if (isset($json['release']) && isset($json['version']) @@ -62,12 +62,12 @@ class Widget_Ajax extends Widget_Abstract_Options implements Widget_Interface_Do && preg_match("/^[0-9\.]+$/", $json['version']) && version_compare($json['release'], $current[0], '>=') && version_compare($json['version'], $current[1], '>')) { - $result = array( + $result = [ 'available' => 1, - 'latest' => $json['release'] . '-' . $json['version'], - 'current' => $current[0] . '-' . $current[1], - 'link' => 'http://typecho.org/download' - ); + 'latest' => $json['release'] . '-' . $json['version'], + 'current' => $current[0] . '-' . $current[1], + 'link' => 'http://typecho.org/download' + ]; } } } catch (Exception $e) { @@ -99,22 +99,22 @@ class Widget_Ajax extends Widget_Abstract_Options implements Widget_Interface_Do $response = $client->getResponseBody(); preg_match_all("/\s*([^>]*)<\/title>\s*<link>([^>]*)<\/link>\s*<guid>[^>]*<\/guid>\s*<pubDate>([^>]*)<\/pubDate>/is", $response, $matches); - $data = array(); + $data = []; 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])) - ); + $data[] = [ + 'title' => $matches[1][$key], + 'link' => $matches[2][$key], + 'date' => date('n.j', strtotime($matches[3][$key])) + ]; if ($key > 8) { break; } } } - + $this->response->throwJson($data); return; } @@ -131,16 +131,16 @@ class Widget_Ajax extends Widget_Abstract_Options implements Widget_Interface_Do 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) { + if ($this->db->fetchObject($this->db->select(['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)); + ->update(['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 - )); + $this->widget('Widget_Abstract_Options')->insert([ + 'name' => 'editorSize', + 'value' => $this->request->size, + 'user' => $this->user->uid + ]); } } diff --git a/var/Widget/Archive.php b/var/Widget/Archive.php index e00defb4..2e63292b 100644 --- a/var/Widget/Archive.php +++ b/var/Widget/Archive.php @@ -24,10 +24,10 @@ class Widget_Archive extends Widget_Abstract_Contents * @var string */ private $_themeFile; - + /** * 风格目录 - * + * * @access private * @var string */ @@ -79,7 +79,7 @@ class Widget_Archive extends Widget_Abstract_Contents * @access private * @var array */ - private $_pageRow = array(); + private $_pageRow = []; /** * 聚合器对象 @@ -159,7 +159,7 @@ class Widget_Archive extends Widget_Abstract_Contents * @access private * @var string */ - private $_archiveTitle = NULL; + private $_archiveTitle = null; /** * 归档类型 @@ -176,12 +176,12 @@ class Widget_Archive extends Widget_Abstract_Contents * @var string */ private $_archiveSingle = false; - + /** * 是否为自定义首页, 主要为了标记自定义首页的情况 - * + * * (default value: false) - * + * * @var boolean * @access private */ @@ -211,19 +211,19 @@ class Widget_Archive extends Widget_Abstract_Contents * @param mixed $params * @throws Typecho_Widget_Exception */ - public function __construct($request, $response, $params = NULL) + public function __construct($request, $response, $params = null) { parent::__construct($request, $response, $params); - $this->parameter->setDefault(array( - 'pageSize' => $this->options->pageSize, - 'type' => NULL, - 'checkPermalink' => true, - 'preview' => false - )); + $this->parameter->setDefault([ + 'pageSize' => $this->options->pageSize, + 'type' => null, + 'checkPermalink' => true, + 'preview' => false + ]); /** 用于判断是路由调用还是外部调用 */ - if (NULL == $this->parameter->type) { + if (null == $this->parameter->type) { $this->parameter->type = Typecho_Router::$current; } else { $this->_invokeFromOutside = true; @@ -233,7 +233,7 @@ class Widget_Archive extends Widget_Abstract_Contents if ($this->parameter->isFeed) { $this->_invokeByFeed = true; } - + /** 初始化皮肤路径 */ $this->_themeDir = rtrim($this->options->themeFile($this->options->theme), '/') . '/'; @@ -288,357 +288,6 @@ class Widget_Archive extends Widget_Abstract_Contents $this->parameter->pageSize = 10; } } - - /** - * 评论地址 - * - * @access protected - * @return string - */ - 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 string $archiveSlug the $_archiveSlug to set - */ - public function setArchiveSlug($archiveSlug) - { - $this->_archiveSlug = $archiveSlug; - } - - /** - * @param string $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 string - */ - public function getArchiveSlug() - { - return $this->_archiveSlug; - } - - /** - * @return string - */ - public function getArchiveSingle() - { - return $this->_archiveSingle; - } - - /** - * @return string - */ - public function getArchiveType() - { - return $this->_archiveType; - } - - /** - * @return string - */ - public function getArchiveTitle() - { - return $this->_archiveTitle; - } - - /** - * @return string - */ - public function getFeedType() - { - return $this->_feedType; - } - - /** - * @return string - */ - public function getDescription() - { - return $this->_description; - } - - /** - * @return string - */ - public function getKeywords() - { - return $this->_keywords; - } - - /** - * @return string - */ - public function getFeedAtomUrl() - { - return $this->_feedAtomUrl; - } - - /** - * @return string - */ - public function getFeedRssUrl() - { - return $this->_feedRssUrl; - } - - /** - * @return string - */ - public function getFeedUrl() - { - return $this->_feedUrl; - } - - /** - * @return Typecho_Feed - */ - public function getFeed() - { - return $this->_feed; - } - - /** - * @return Typecho_Db_Query - */ - public function getCountSql() - { - return $this->_countSql; - } - - /** - * @return int - */ - public function getTotal() - { - if (false === $this->_total) { - $this->_total = $this->size($this->_countSql); - } - - return $this->_total; - } - - /** - * @return int - */ - public function getCurrentPage() - { - return $this->_currentPage; - } - - /** - * 获取页数 - * - * @return integer - */ - public function getTotalPage() - { - return ceil($this->getTotal() / $this->parameter->pageSize); - } - - /** - * @return string - */ - public function getThemeFile() - { - return $this->_themeFile; - } - - /** - * @return string - */ - 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'] || urldecode($src['path']) != urldecode($target['path'])) { - $this->response->redirect($permalink, true); - } - } /** * 导入对象 @@ -672,605 +321,296 @@ class Widget_Archive extends Widget_Abstract_Contents } /** - * 处理index - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 + * 增加标题 + * @param string $archiveTitle 标题 * @return void */ - private function indexHandle(Typecho_Db_Query $select, &$hasPushed) + public function addArchiveTitle($archiveTitle) { - $select->where('table.contents.type = ?', 'post'); - - /** 插件接口 */ - $this->pluginHandle()->indexHandle($this, $select); + $current = $this->getArchiveTitle(); + $current[] = $archiveTitle; + $this->setArchiveTitle($current); } /** - * 默认的非首页归档处理 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - * @throws Typecho_Widget_Exception + * @return string */ - private function archiveEmptyHandle(Typecho_Db_Query $select, &$hasPushed) + public function getArchiveTitle() { - throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404); + return $this->_archiveTitle; } /** - * 404页面处理 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void + * @param $archiveTitle the $_archiveTitle to set */ - private function error404Handle(Typecho_Db_Query $select, &$hasPushed) + public function setArchiveTitle($archiveTitle) { - /** 设置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); + $this->_archiveTitle = $archiveTitle; } /** - * 独立页处理 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - * @throws Typecho_Widget_Exception + * 获取分页对象 + * @return array */ - private function singleHandle(Typecho_Db_Query $select, &$hasPushed) + public function getPageRow() { - 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'; - - /** 匹配类型 */ - - if ('single' != $this->parameter->type) { - $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) && !$this->parameter->preview) { - $select->where('table.contents.slug = ?', $this->request->slug); - } - - /** 匹配时间 */ - if (isset($this->request->year) && !$this->parameter->preview) { - $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 */ - $isPasswordPosted = false; - - if ($this->request->isPost() - && isset($this->request->protectPassword) - && !$this->parameter->preview) { - $this->security->protect(); - Typecho_Cookie::set( - 'protectPassword_' . $this->request->filter('int')->protectCID, - $this->request->protectPassword, - 0 - ); - - $isPasswordPosted = true; - } - - /** 匹配类型 */ - $select->limit(1); - $this->query($select); - - if (!$this->have() - || (isset($this->request->category) && $this->category != $this->request->category && !$this->parameter->preview) - || (isset($this->request->directory) && $this->request->directory != implode('/', $this->directory) && !$this->parameter->preview)) { - if (!$this->_invokeFromOutside) { - /** 对没有索引情况下的判断 */ - throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404); - } else { - $hasPushed = true; - return; - } - } - - /** 密码表单判断逻辑 */ - if ($isPasswordPosted && $this->hidden) { - throw new Typecho_Widget_Exception(_t('对不起,您输入的密码错误'), 403); - } - - /** 设置模板 */ - 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; - } - - /** 设置归档类型 */ - list($this->_archiveType) = explode('_', $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); + return $this->_pageRow; } /** - * 处理分类 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 + * 设置分页对象 + * @param array $pageRow * @return void - * @throws Typecho_Widget_Exception */ - private function categoryHandle(Typecho_Db_Query $select, &$hasPushed) + public function setPageRow($pageRow) { - /** 如果是分类 */ - $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); - } - - if (isset($this->request->directory)) { - $directory = explode('/', $this->request->directory); - $categorySelect->where('slug = ?', $directory[count($directory) - 1]); - } - - $category = $this->db->fetchRow($categorySelect); - if (empty($category)) { - throw new Typecho_Widget_Exception(_t('分类不存在'), 404); - } - - $categoryListWidget = $this->widget('Widget_Metas_Category_List', 'current=' . $category['mid']); - $category = $categoryListWidget->filter($category); - - if (isset($directory) && ($this->request->directory != implode('/', $category['directory']))) { - throw new Typecho_Widget_Exception(_t('父级分类不存在'), 404); - } - - $children = $categoryListWidget->getAllChildren($category['mid']); - $children[] = $category['mid']; - - /** fix sql92 by 70 */ - $select->join('table.relationships', 'table.contents.cid = table.relationships.cid') - ->where('table.relationships.mid IN ?', $children) - ->where('table.contents.type = ?', 'post') - ->group('table.contents.cid'); - - /** 设置分页 */ - $this->_pageRow = array_merge($category, array( - 'slug' => urlencode($category['slug']), - 'directory' => implode('/', array_map('urlencode', $category['directory'])) - )); - - /** 设置关键词 */ - $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); + $this->_pageRow = $pageRow; } /** - * 处理标签 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - * @throws Typecho_Widget_Exception + * @return string */ - private function tagHandle(Typecho_Db_Query $select, &$hasPushed) + public function getArchiveSlug() { - $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); + return $this->_archiveSlug; } /** - * 处理作者 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - * @throws Typecho_Widget_Exception + * @param string $archiveSlug the $_archiveSlug to set */ - private function authorHandle(Typecho_Db_Query $select, &$hasPushed) + public function setArchiveSlug($archiveSlug) { - $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); + $this->_archiveSlug = $archiveSlug; } /** - * 处理日期 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void + * @return string */ - private function dateHandle(Typecho_Db_Query $select, &$hasPushed) + public function getArchiveSingle() { - /** 如果是按日期归档 */ - $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); + return $this->_archiveSingle; } /** - * 处理搜索 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void + * @param string $archiveSingle the $_archiveSingle to set */ - private function searchHandle(Typecho_Db_Query $select, &$hasPushed) + public function setArchiveSingle($archiveSingle) { - /** 增加自定义搜索引擎接口 */ - //~ fix issue 40 - $keywords = $this->request->filter('url', 'search')->keywords; - $this->pluginHandle()->trigger($hasPushed)->search($keywords, $this); + $this->_archiveSingle = $archiveSingle; + } - if (!$hasPushed) { - $searchQuery = '%' . str_replace(' ', '%', $keywords) . '%'; + /** + * @return string + */ + public function getArchiveType() + { + return $this->_archiveType; + } - /** 搜索无法进入隐私项保护归档 */ - if ($this->user->hasLogin()) { - //~ fix issue 941 - $select->where("table.contents.password IS NULL OR table.contents.password = '' OR table.contents.authorId = ?", $this->user->uid); - } else { - $select->where("table.contents.password IS NULL OR table.contents.password = ''"); - } + /** + * @param $archiveType the $_archiveType to set + */ + public function setArchiveType($archiveType) + { + $this->_archiveType = $archiveType; + } - $select->where('table.contents.title LIKE ? OR table.contents.text LIKE ?', $searchQuery, $searchQuery) - ->where('table.contents.type = ?', 'post'); - } + /** + * @return string + */ + public function getFeedType() + { + return $this->_feedType; + } - /** 设置关键词 */ + /** + * @param $feedType the $_feedType to set + */ + public function setFeedType($feedType) + { + $this->_feedType = $feedType; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * @param $description the $_description to set + */ + public function setDescription($description) + { + $this->_description = $description; + } + + /** + * @return string + */ + public function getKeywords() + { + return $this->_keywords; + } + + /** + * @param $keywords the $_keywords to set + */ + public function setKeywords($keywords) + { $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->_archiveSlug = $keywords; - - /** 插件接口 */ - $this->pluginHandle()->searchHandle($this, $select); } /** - * 重载select - * - * @access public + * @return string + */ + public function getFeedAtomUrl() + { + return $this->_feedAtomUrl; + } + + /** + * @param $feedAtomUrl the $_feedAtomUrl to set + */ + public function setFeedAtomUrl($feedAtomUrl) + { + $this->_feedAtomUrl = $feedAtomUrl; + } + + /** + * @return string + */ + public function getFeedRssUrl() + { + return $this->_feedRssUrl; + } + + /** + * @param $feedRssUrl the $_feedRssUrl to set + */ + public function setFeedRssUrl($feedRssUrl) + { + $this->_feedRssUrl = $feedRssUrl; + } + + /** + * @return string + */ + public function getFeedUrl() + { + return $this->_feedUrl; + } + + /** + * @param $feedUrl the $_feedUrl to set + */ + public function setFeedUrl($feedUrl) + { + $this->_feedUrl = $feedUrl; + } + + /** + * @return Typecho_Feed + */ + public function getFeed() + { + return $this->_feed; + } + + /** + * @param $feed the $_feed to set + */ + public function setFeed($feed) + { + $this->_feed = $feed; + } + + /** * @return Typecho_Db_Query */ - public function select() + public function getCountSql() { - if ($this->_invokeByFeed) { - // 对feed输出加入限制条件 - return parent::select()->where('table.contents.allowFeed = ?', 1) - ->where("table.contents.password IS NULL OR table.contents.password = ''"); - } else { - return parent::select(); - } + return $this->_countSql; } /** - * 提交查询 - * - * @access public - * @param mixed $select 查询对象 - * @return void + * @param $countSql the $_countSql to set */ - public function query($select) + public function setCountSql($countSql) { - $this->pluginHandle()->trigger($queryPlugged)->query($this, $select); - if (!$queryPlugged) { - $this->db->fetchAll($select, array($this, 'push')); + $this->_countSql = $countSql; + } + + /** + * @return int + */ + public function getCurrentPage() + { + return $this->_currentPage; + } + + /** + * 获取页数 + * + * @return integer + */ + public function getTotalPage() + { + return ceil($this->getTotal() / $this->parameter->pageSize); + } + + /** + * @return int + */ + public function getTotal() + { + if (false === $this->_total) { + $this->_total = $this->size($this->_countSql); } + + return $this->_total; + } + + /** + * @param $total the $_total to set + */ + public function setTotal($total) + { + $this->_total = $total; + } + + /** + * @return string + */ + public function getThemeFile() + { + return $this->_themeFile; + } + + /** + * @param $themeFile the $_themeFile to set + */ + public function setThemeFile($themeFile) + { + $this->_themeFile = $themeFile; + } + + /** + * @return string + */ + public function getThemeDir() + { + return $this->_themeDir; + } + + /** + * @param $themeDir the $_themeDir to set + */ + public function setThemeDir($themeDir) + { + $this->_themeDir = $themeDir; } /** @@ -1286,41 +626,41 @@ class Widget_Archive extends Widget_Abstract_Contents return; } - $handles = array( - 'index' => 'indexHandle', - 'index_page' => 'indexHandle', - 'archive' => 'archiveEmptyHandle', - 'archive_page' => 'archiveEmptyHandle', - 404 => 'error404Handle', - 'single' => 'singleHandle', - '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' - ); + $handles = [ + 'index' => 'indexHandle', + 'index_page' => 'indexHandle', + 'archive' => 'archiveEmptyHandle', + 'archive_page' => 'archiveEmptyHandle', + 404 => 'error404Handle', + 'single' => 'singleHandle', + '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) { + if (null != $filterKeywords) { $this->response->redirect(Typecho_Router::url('search', - array('keywords' => urlencode($filterKeywords)), $this->options->index)); + ['keywords' => urlencode($filterKeywords)], $this->options->index)); } } @@ -1333,7 +673,7 @@ class Widget_Archive extends Widget_Abstract_Contents $this->request->setParam('cid', intval(substr($frontPage, 5))); $this->parameter->type = 'page'; $this->_makeSinglePageAsFrontPage = true; - } else if (0 === strpos($frontPage, 'file:')) { + } elseif (0 === strpos($frontPage, 'file:')) { // 显示某个文件 $this->setThemeFile(substr($frontPage, 5)); return; @@ -1415,10 +755,27 @@ class Widget_Archive extends Widget_Abstract_Contents $this->_countSql = clone $select; $select->order('table.contents.created', Typecho_Db::SORT_DESC) - ->page($this->_currentPage, $this->parameter->pageSize); + ->page($this->_currentPage, $this->parameter->pageSize); $this->query($select); } + /** + * 重载select + * + * @access public + * @return Typecho_Db_Query + */ + public function select() + { + if ($this->_invokeByFeed) { + // 对feed输出加入限制条件 + return parent::select()->where('table.contents.allowFeed = ?', 1) + ->where("table.contents.password IS NULL OR table.contents.password = ''"); + } else { + return parent::select(); + } + } + /** * 输出文章内容 * @@ -1426,7 +783,7 @@ class Widget_Archive extends Widget_Abstract_Contents * @param string $more 文章截取后缀 * @return void */ - public function content($more = NULL) + public function content($more = null) { parent::content($this->is('single') ? false : $more); } @@ -1446,10 +803,10 @@ class Widget_Archive extends Widget_Abstract_Contents { if ($this->have()) { $hasNav = false; - $default = array( - 'wrapTag' => 'ol', - 'wrapClass' => 'page-navigator' - ); + $default = [ + 'wrapTag' => 'ol', + 'wrapClass' => 'page-navigator' + ]; if (is_string($template)) { parse_str($template, $config); @@ -1458,22 +815,22 @@ class Widget_Archive extends Widget_Abstract_Contents } $template = array_merge($default, $config); - + $total = $this->getTotal(); - $this->pluginHandle()->trigger($hasNav)->pageNav($this->_currentPage, $total, + $this->pluginHandle()->trigger($hasNav)->pageNav($this->_currentPage, $total, $this->parameter->pageSize, $prev, $next, $splitPage, $splitWord); if (!$hasNav && $total > $this->parameter->pageSize) { $query = Typecho_Router::url($this->parameter->type . - (false === strpos($this->parameter->type, '_page') ? '_page' : NULL), - $this->_pageRow, $this->options->index); + (false === strpos($this->parameter->type, '_page') ? '_page' : null), + $this->_pageRow, $this->options->index); /** 使用盒状分页 */ - $nav = new Typecho_Widget_Helper_PageNavigator_Box($total, + $nav = new Typecho_Widget_Helper_PageNavigator_Box($total, $this->_currentPage, $this->parameter->pageSize, $query); - - echo '<' . $template['wrapTag'] . (empty($template['wrapClass']) - ? '' : ' class="' . $template['wrapClass'] . '"') . '>'; + + echo '<' . $template['wrapTag'] . (empty($template['wrapClass']) + ? '' : ' class="' . $template['wrapClass'] . '"') . '>'; $nav->render($prev, $next, $splitPage, $splitWord, $template); echo '</' . $template['wrapTag'] . '>'; } @@ -1493,12 +850,12 @@ class Widget_Archive extends Widget_Abstract_Contents 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); + (false === strpos($this->parameter->type, '_page') ? '_page' : null), + $this->_pageRow, $this->options->index); /** 使用盒状分页 */ $this->_pageNav = new Typecho_Widget_Helper_PageNavigator_Classic($this->getTotal(), - $this->_currentPage, $this->parameter->pageSize, $query); + $this->_currentPage, $this->parameter->pageSize, $query); } $this->_pageNav->{$page}($word); @@ -1513,30 +870,30 @@ class Widget_Archive extends Widget_Abstract_Contents */ public function comments() { - $parameter = array( + $parameter = [ '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 Widget_Comments_Ping */ public function pings() { - return $this->widget('Widget_Comments_Ping', array( + return $this->widget('Widget_Comments_Ping', [ 'parentId' => $this->hidden ? 0 : $this->cid, 'parentContent' => $this->row, - 'allowPing' => $this->allow('ping') - )); + 'allowPing' => $this->allow('ping') + ]); } /** @@ -1549,11 +906,11 @@ class Widget_Archive extends Widget_Abstract_Contents */ public function attachments($limit = 0, $offset = 0) { - return $this->widget('Widget_Contents_Attachment_Related@' . $this->cid . '-' . uniqid(), array( - 'parentId' => $this->cid, - 'limit' => $limit, - 'offset' => $offset - )); + return $this->widget('Widget_Contents_Attachment_Related@' . $this->cid . '-' . uniqid(), [ + 'parentId' => $this->cid, + 'limit' => $limit, + 'offset' => $offset + ]); } /** @@ -1565,7 +922,7 @@ class Widget_Archive extends Widget_Abstract_Contents * @param array $custom 定制化样式 * @return void */ - public function theNext($format = '%s', $default = NULL, $custom = array()) + public function theNext($format = '%s', $default = null, $custom = []) { $content = $this->db->fetchRow($this->select()->where('table.contents.created > ? AND table.contents.created < ?', $this->created, $this->options->time) @@ -1577,10 +934,10 @@ class Widget_Archive extends Widget_Abstract_Contents if ($content) { $content = $this->filter($content); - $default = array( - 'title' => NULL, - 'tagClass' => NULL - ); + $default = [ + 'title' => null, + 'tagClass' => null + ]; $custom = array_merge($default, $custom); extract($custom); @@ -1603,7 +960,7 @@ class Widget_Archive extends Widget_Abstract_Contents * @param array $custom 定制化样式 * @return void */ - public function thePrev($format = '%s', $default = NULL, $custom = array()) + public function thePrev($format = '%s', $default = null, $custom = []) { $content = $this->db->fetchRow($this->select()->where('table.contents.created < ?', $this->created) ->where('table.contents.status = ?', 'publish') @@ -1614,10 +971,10 @@ class Widget_Archive extends Widget_Abstract_Contents if ($content) { $content = $this->filter($content); - $default = array( - 'title' => NULL, - 'tagClass' => NULL - ); + $default = [ + 'title' => null, + 'tagClass' => null + ]; $custom = array_merge($default, $custom); extract($custom); @@ -1639,7 +996,7 @@ class Widget_Archive extends Widget_Abstract_Contents * @param string $type 关联类型 * @return Typecho_Widget */ - public function related($limit = 5, $type = NULL) + public function related($limit = 5, $type = null) { $type = strtolower($type); @@ -1647,11 +1004,11 @@ class Widget_Archive extends Widget_Abstract_Contents case 'author': /** 如果访问权限被设置为禁止,则tag会被置为空 */ return $this->widget('Widget_Contents_Related_Author', - array('cid' => $this->cid, 'type' => $this->type, 'author' => $this->author->uid, 'limit' => $limit)); + ['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)); + ['cid' => $this->cid, 'type' => $this->type, 'tags' => $this->tags, 'limit' => $limit]); } } @@ -1662,23 +1019,23 @@ class Widget_Archive extends Widget_Abstract_Contents * @param string $rule 规则 * @return void */ - public function header($rule = NULL) + 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, - 'antiSpam' => 1, - 'atom' => $this->_feedAtomUrl - ); + $rules = []; + $allows = [ + '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, + 'antiSpam' => 1, + 'atom' => $this->_feedAtomUrl + ]; /** 头部是否输出聚合 */ $allowFeed = !$this->is('single') || $this->allow('feed') || $this->_makeSinglePageAsFrontPage; @@ -1731,7 +1088,7 @@ class Widget_Archive extends Widget_Abstract_Contents if (!empty($allows['atom']) && $allowFeed) { $header .= '<link rel="alternate" type="application/atom+xml" title="' . $title . ' » ATOM 1.0" href="' . $allows['atom'] . '" />' . "\n"; } - + if ($this->options->commentsThreaded && $this->is('single')) { if ('' != $allows['commentReply']) { if (1 == $allows['commentReply']) { @@ -1836,7 +1193,7 @@ class Widget_Archive extends Widget_Abstract_Contents input.type = 'hidden'; input.name = '_'; input.value = " . Typecho_Common::shuffleScriptVar( - $this->security->getToken($this->request->getRequestUrl())) . " + $this->security->getToken($this->request->getRequestUrl())) . " if (null != r) { var forms = r.getElementsByTagName('form'); @@ -1893,10 +1250,10 @@ class Widget_Archive extends Widget_Abstract_Contents public function remember($cookieName, $return = false) { $cookieName = strtolower($cookieName); - if (!in_array($cookieName, array('author', 'mail', 'url'))) { + if (!in_array($cookieName, ['author', 'mail', 'url'])) { return ''; } - + $value = Typecho_Cookie::get('__typecho_remember_' . $cookieName); if ($return) { return $value; @@ -1907,14 +1264,14 @@ class Widget_Archive extends Widget_Abstract_Contents /** * 输出归档标题 - * - * @param mixed $defines - * @param string $before - * @param string $end + * + * @param mixed $defines + * @param string $before + * @param string $end * @access public * @return void */ - public function archiveTitle($defines = NULL, $before = ' » ', $end = '') + public function archiveTitle($defines = null, $before = ' » ', $end = '') { if ($this->_archiveTitle) { $define = '%s'; @@ -1936,22 +1293,6 @@ class Widget_Archive extends Widget_Abstract_Contents 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); - } - /** * 获取主题文件 * @@ -1974,7 +1315,7 @@ class Widget_Archive extends Widget_Abstract_Contents { /** 处理静态链接跳转 */ $this->checkPermalink(); - + /** 添加Pingback */ if (2 == $this->options->allowXmlRpc) { $this->response->setHeader('X-Pingback', $this->options->xmlRpcUrl); @@ -1987,7 +1328,7 @@ class Widget_Archive extends Widget_Abstract_Contents $validated = true; } } - + if (!$validated && !empty($this->_archiveType)) { //~ 首先找具体路径, 比如 category/default.php @@ -2013,7 +1354,7 @@ class Widget_Archive extends Widget_Abstract_Contents if (file_exists($this->_themeDir . 'page.php')) { $this->_themeFile = 'page.php'; $validated = true; - } else if (file_exists($this->_themeDir . 'post.php')) { + } elseif (file_exists($this->_themeDir . 'post.php')) { $this->_themeFile = 'post.php'; $validated = true; } @@ -2052,6 +1393,43 @@ class Widget_Archive extends Widget_Abstract_Contents $this->pluginHandle()->afterRender($this); } + /** + * 检查链接是否正确 + * + * @access private + * @return void + */ + private function checkPermalink() + { + $type = $this->parameter->type; + + if (in_array($type, ['index', 'comment_page', 404]) + || $this->_makeSinglePageAsFrontPage // 自定义首页不处理 + || !$this->parameter->checkPermalink) { // 强制关闭 + return; + } + + if ($this->_archiveSingle) { + $permalink = $this->permalink; + } else { + $value = array_merge($this->_pageRow, [ + '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'] || urldecode($src['path']) != urldecode($target['path'])) { + $this->response->redirect($permalink, true); + } + } + /** * 输出feed * @@ -2064,13 +1442,13 @@ class Widget_Archive extends Widget_Abstract_Contents $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)); + || '/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))); + $this->options->title . ($this->_archiveTitle ? ' - ' . $this->_archiveTitle : null))); if ('comments' == $this->parameter->type) { $comments = $this->widget('Widget_Comments_Recent', 'pageSize=10'); @@ -2081,58 +1459,680 @@ class Widget_Archive extends Widget_Abstract_Contents while ($comments->next()) { $suffix = $this->pluginHandle()->trigger($plugged)->commentFeedItem($this->_feedType, $comments); if (!$plugged) { - $suffix = NULL; + $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 - )); + $this->_feed->addItem([ + 'title' => $comments->author, + 'content' => $comments->content, + 'date' => $comments->created, + 'link' => $comments->permalink, + 'author' => (object)[ + '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)); + $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; + $suffix = null; } $feedUrl = ''; if (Typecho_Feed::RSS2 == $this->_feedType) { $feedUrl = $this->feedUrl; - } else if (Typecho_Feed::RSS1 == $this->_feedType) { + } elseif (Typecho_Feed::RSS1 == $this->_feedType) { $feedUrl = $this->feedRssUrl; - } else if (Typecho_Feed::ATOM1 == $this->_feedType) { + } elseif (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, + $this->_feed->addItem([ + '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 - )); + 'suffix' => $suffix + ]); } } $this->response->setContentType($this->_feedContentType); echo $this->_feed->__toString(); } + + /** + * 评论地址 + * + * @access protected + * @return string + */ + protected function ___commentUrl() + { + /** 生成反馈地址 */ + /** 评论 */ + $commentUrl = parent::___commentUrl(); + + //不依赖js的父级评论 + $reply = $this->request->filter('int')->replyTo; + if ($reply && $this->is('single')) { + $commentUrl .= '?parent=' . $reply; + } + + return $commentUrl; + } + + /** + * 判断归档类型和名称 + * + * @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) || $archiveSlug == $this->_archiveSlug); + } + + /** + * 处理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); + } + + /** + * 默认的非首页归档处理 + * + * @access private + * @param Typecho_Db_Query $select 查询对象 + * @param boolean $hasPushed 是否已经压入队列 + * @return void + * @throws Typecho_Widget_Exception + */ + private function archiveEmptyHandle(Typecho_Db_Query $select, &$hasPushed) + { + throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404); + } + + /** + * 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 + * @throws Typecho_Widget_Exception + */ + private function singleHandle(Typecho_Db_Query $select, &$hasPushed) + { + if ('comment_page' == $this->parameter->type) { + $params = []; + $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'; + + /** 匹配类型 */ + + if ('single' != $this->parameter->type) { + $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) && !$this->parameter->preview) { + $select->where('table.contents.slug = ?', $this->request->slug); + } + + /** 匹配时间 */ + if (isset($this->request->year) && !$this->parameter->preview) { + $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 */ + $isPasswordPosted = false; + + if ($this->request->isPost() + && isset($this->request->protectPassword) + && !$this->parameter->preview) { + $this->security->protect(); + Typecho_Cookie::set( + 'protectPassword_' . $this->request->filter('int')->protectCID, + $this->request->protectPassword, + 0 + ); + + $isPasswordPosted = true; + } + + /** 匹配类型 */ + $select->limit(1); + $this->query($select); + + if (!$this->have() + || (isset($this->request->category) && $this->category != $this->request->category && !$this->parameter->preview) + || (isset($this->request->directory) && $this->request->directory != implode('/', $this->directory) && !$this->parameter->preview)) { + if (!$this->_invokeFromOutside) { + /** 对没有索引情况下的判断 */ + throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404); + } else { + $hasPushed = true; + return; + } + } + + /** 密码表单判断逻辑 */ + if ($isPasswordPosted && $this->hidden) { + throw new Typecho_Widget_Exception(_t('对不起,您输入的密码错误'), 403); + } + + /** 设置模板 */ + 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] = explode('_', $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 public + * @param mixed $select 查询对象 + * @return void + */ + public function query($select) + { + $this->pluginHandle()->trigger($queryPlugged)->query($this, $select); + if (!$queryPlugged) { + $this->db->fetchAll($select, [$this, 'push']); + } + } + + /** + * 处理分类 + * + * @access private + * @param Typecho_Db_Query $select 查询对象 + * @param boolean $hasPushed 是否已经压入队列 + * @return void + * @throws Typecho_Widget_Exception + */ + 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); + } + + if (isset($this->request->directory)) { + $directory = explode('/', $this->request->directory); + $categorySelect->where('slug = ?', $directory[count($directory) - 1]); + } + + $category = $this->db->fetchRow($categorySelect); + if (empty($category)) { + throw new Typecho_Widget_Exception(_t('分类不存在'), 404); + } + + $categoryListWidget = $this->widget('Widget_Metas_Category_List', 'current=' . $category['mid']); + $category = $categoryListWidget->filter($category); + + if (isset($directory) && ($this->request->directory != implode('/', $category['directory']))) { + throw new Typecho_Widget_Exception(_t('父级分类不存在'), 404); + } + + $children = $categoryListWidget->getAllChildren($category['mid']); + $children[] = $category['mid']; + + /** fix sql92 by 70 */ + $select->join('table.relationships', 'table.contents.cid = table.relationships.cid') + ->where('table.relationships.mid IN ?', $children) + ->where('table.contents.type = ?', 'post') + ->group('table.contents.cid'); + + /** 设置分页 */ + $this->_pageRow = array_merge($category, [ + 'slug' => urlencode($category['slug']), + 'directory' => implode('/', array_map('urlencode', $category['directory'])) + ]); + + /** 设置关键词 */ + $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 + * @throws Typecho_Widget_Exception + */ + 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, + [$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, [ + '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 + * @throws Typecho_Widget_Exception + */ + 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), + [$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); + } elseif (!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); + } elseif (!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 = ['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) . '%'; + + /** 搜索无法进入隐私项保护归档 */ + if ($this->user->hasLogin()) { + //~ fix issue 941 + $select->where("table.contents.password IS NULL OR table.contents.password = '' OR table.contents.authorId = ?", $this->user->uid); + } else { + $select->where("table.contents.password IS NULL OR table.contents.password = ''"); + } + + $select->where('table.contents.title LIKE ? OR table.contents.text LIKE ?', $searchQuery, $searchQuery) + ->where('table.contents.type = ?', 'post'); + } + + /** 设置关键词 */ + $this->_keywords = $keywords; + + /** 设置分页 */ + $this->_pageRow = ['keywords' => urlencode($keywords)]; + + /** 设置头部feed */ + /** RSS 2.0 */ + $this->_feedUrl = Typecho_Router::url('search', ['keywords' => $keywords], $this->options->feedUrl); + + /** RSS 1.0 */ + $this->_feedRssUrl = Typecho_Router::url('search', ['keywords' => $keywords], $this->options->feedAtomUrl); + + /** ATOM 1.0 */ + $this->_feedAtomUrl = Typecho_Router::url('search', ['keywords' => $keywords], $this->options->feedAtomUrl); + + /** 设置标题 */ + $this->_archiveTitle = $keywords; + + /** 设置归档类型 */ + $this->_archiveType = 'search'; + + /** 设置归档缩略名 */ + $this->_archiveSlug = $keywords; + + /** 插件接口 */ + $this->pluginHandle()->searchHandle($this, $select); + } } diff --git a/var/Widget/Backup.php b/var/Widget/Backup.php index 02749b74..876df567 100644 --- a/var/Widget/Backup.php +++ b/var/Widget/Backup.php @@ -20,48 +20,48 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_ /** * @var array */ - private $_types = array( - 'contents' => 1, - 'comments' => 2, - 'metas' => 3, - 'relationships' => 4, - 'users' => 5, - 'fields' => 6 - ); + private $_types = [ + 'contents' => 1, + 'comments' => 2, + 'metas' => 3, + 'relationships' => 4, + 'users' => 5, + 'fields' => 6 + ]; /** * @var array */ - private $_fields = array( - 'contents' => array( + private $_fields = [ + 'contents' => [ 'cid', 'title', 'slug', 'created', 'modified', 'text', 'order', 'authorId', 'template', 'type', 'status', 'password', 'commentsNum', 'allowComment', 'allowPing', 'allowFeed', 'parent' - ), - 'comments' => array( + ], + 'comments' => [ 'coid', 'cid', 'created', 'author', 'authorId', 'ownerId', 'mail', 'url', 'ip', 'agent', 'text', 'type', 'status', 'parent' - ), - 'metas' => array( + ], + 'metas' => [ 'mid', 'name', 'slug', 'type', 'description', 'count', 'order', 'parent' - ), - 'relationships' => array('cid', 'mid'), - 'users' => array( + ], + 'relationships' => ['cid', 'mid'], + 'users' => [ 'uid', 'name', 'password', 'mail', 'url', 'screenName', 'created', 'activated', 'logged', 'group', 'authCode' - ), - 'fields' => array( + ], + 'fields' => [ 'cid', 'name', 'type', 'str_value', 'int_value', 'float_value' - ) - ); + ] + ]; /** * @var array */ - private $_lastIds = array(); + private $_lastIds = []; /** * @var array */ - private $_cleared = array(); + private $_cleared = []; /** * @var bool @@ -69,30 +69,67 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_ private $_login = false; /** - * 过滤字段 + * 列出已有备份文件 * - * @param $table - * @param $data * @return array */ - private function applyFields($table, $data) + public function listFiles() { - $result = array(); + return array_map('basename', glob(__TYPECHO_BACKUP_DIR__ . '/*.dat')); + } - foreach ($data as $key => $val) { - $index = array_search($key, $this->_fields[$table]); + /** + * 绑定动作 + */ + public function action() + { + $this->user->pass('administrator'); + $this->security->protect(); - if ($index !== false) { - $result[$key] = $val; + $this->on($this->request->is('do=export'))->export(); + $this->on($this->request->is('do=import'))->import(); + } - if ($index === 0 && !in_array($table, array('relationships', 'fields'))) { - $this->_lastIds[$table] = isset($this->_lastIds[$table]) - ? max($this->_lastIds[$table], $val) : $val; + /** + * 导出数据 + */ + private function export() + { + $host = parse_url($this->options->siteUrl, PHP_URL_HOST); + $this->response->setContentType('application/octet-stream'); + $this->response->setHeader('Content-Disposition', 'attachment; filename="' + . date('Ymd') . '_' . $host . '_' . uniqid() . '.dat"'); + + $header = str_replace('XXXX', self::HEADER_VERSION, self::HEADER); + $buffer = $header; + $db = $this->db; + + foreach ($this->_types as $type => $val) { + $page = 1; + do { + $rows = $db->fetchAll($db->select()->from('table.' . $type)->page($page, 20)); + $page ++; + + foreach ($rows as $row) { + $buffer .= $this->buildBuffer($val, $this->applyFields($type, $row)); + + if (strlen($buffer) >= 1024 * 1024) { + echo $buffer; + ob_flush(); + $buffer = ''; + } } - } + } while (count($rows) == 20); } - return $result; + if (!empty($buffer)) { + echo $buffer; + ob_flush(); + } + + Typecho_Plugin::factory(__CLASS__)->export(); + echo $header; + ob_end_flush(); } /** @@ -103,10 +140,10 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_ private function buildBuffer($type, $data) { $body = ''; - $schema = array(); + $schema = []; foreach ($data as $key => $val) { - $schema[$key] = NULL === $val ? NULL : strlen($val); + $schema[$key] = null === $val ? null : strlen($val); $body .= $val; } @@ -115,21 +152,63 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_ } /** - * @param $str - * @param $version - * @return bool + * 过滤字段 + * + * @param $table + * @param $data + * @return array */ - private function parseHeader($str, &$version) { - if (!$str || strlen($str) != strlen(self::HEADER)) { - return false; + private function applyFields($table, $data) + { + $result = []; + + foreach ($data as $key => $val) { + $index = array_search($key, $this->_fields[$table]); + + if ($index !== false) { + $result[$key] = $val; + + if ($index === 0 && !in_array($table, ['relationships', 'fields'])) { + $this->_lastIds[$table] = isset($this->_lastIds[$table]) + ? max($this->_lastIds[$table], $val) : $val; + } + } } - if (!preg_match("/%TYPECHO_BACKUP_[A-Z0-9]{4}%/", $str)) { - return false; + return $result; + } + + /** + * 导入数据 + */ + private function import() + { + $path = null; + + if (!empty($_FILES)) { + $file = array_pop($_FILES); + + if (0 == $file['error'] && is_uploaded_file($file['tmp_name'])) { + $path = $file['tmp_name']; + } else { + $this->widget('Widget_Notice')->set(_t('备份文件上传失败'), 'error'); + $this->response->goBack(); + } + } else { + if (!$this->request->is('file')) { + $this->widget('Widget_Notice')->set(_t('没有选择任何备份文件'), 'error'); + $this->response->goBack(); + } + + $path = __TYPECHO_BACKUP_DIR__ . '/' . $this->request->get('file'); + + if (!file_exists($path)) { + $this->widget('Widget_Notice')->set(_t('备份文件不存在'), 'error'); + $this->response->goBack(); + } } - $version = substr($str, 16, -1); - return true; + $this->extractData($path); } /** @@ -184,7 +263,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_ $this->response->goBack(); } - list ($type, $header, $body) = $data; + [$type, $header, $body] = $data; $this->processData($type, $header, $body); } @@ -201,6 +280,25 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_ $this->response->goBack(); } + /** + * @param $str + * @param $version + * @return bool + */ + private function parseHeader($str, &$version) + { + if (!$str || strlen($str) != strlen(self::HEADER)) { + return false; + } + + if (!preg_match("/%TYPECHO_BACKUP_[A-Z0-9]{4}%/", $str)) { + return false; + } + + $version = substr($str, 16, - 1); + return true; + } + /** * @param $type * @param $header @@ -212,11 +310,11 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_ if (!empty($table)) { $schema = Json::decode($header, true); - $data = array(); + $data = []; $offset = 0; foreach ($schema as $key => $val) { - $data[$key] = NULL === $val ? NULL : substr($body, $offset, $val); + $data[$key] = null === $val ? null : substr($body, $offset, $val); $offset += $val; } @@ -276,101 +374,4 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_ Typecho_Cookie::set('__typecho_authCode', Typecho_Common::hash($user['authCode'])); $this->_login = true; } - - /** - * 导出数据 - */ - private function export() - { - $host = parse_url($this->options->siteUrl, PHP_URL_HOST); - $this->response->setContentType('application/octet-stream'); - $this->response->setHeader('Content-Disposition', 'attachment; filename="' - . date('Ymd') . '_' . $host . '_' . uniqid() . '.dat"'); - - $header = str_replace('XXXX', self::HEADER_VERSION, self::HEADER); - $buffer = $header; - $db = $this->db; - - foreach ($this->_types as $type => $val) { - $page = 1; - do { - $rows = $db->fetchAll($db->select()->from('table.' . $type)->page($page, 20)); - $page ++; - - foreach ($rows as $row) { - $buffer .= $this->buildBuffer($val, $this->applyFields($type, $row)); - - if (strlen($buffer) >= 1024 * 1024) { - echo $buffer; - ob_flush(); - $buffer = ''; - } - } - } while (count($rows) == 20); - } - - if (!empty($buffer)) { - echo $buffer; - ob_flush(); - } - - Typecho_Plugin::factory(__CLASS__)->export(); - echo $header; - ob_end_flush(); - } - - /** - * 导入数据 - */ - private function import() - { - $path = NULL; - - if (!empty($_FILES)) { - $file = array_pop($_FILES); - - if (0 == $file['error'] && is_uploaded_file($file['tmp_name'])) { - $path = $file['tmp_name']; - } else { - $this->widget('Widget_Notice')->set(_t('备份文件上传失败'), 'error'); - $this->response->goBack(); - } - } else { - if (!$this->request->is('file')) { - $this->widget('Widget_Notice')->set(_t('没有选择任何备份文件'), 'error'); - $this->response->goBack(); - } - - $path = __TYPECHO_BACKUP_DIR__ . '/' . $this->request->get('file'); - - if (!file_exists($path)) { - $this->widget('Widget_Notice')->set(_t('备份文件不存在'), 'error'); - $this->response->goBack(); - } - } - - $this->extractData($path); - } - - /** - * 列出已有备份文件 - * - * @return array - */ - public function listFiles() - { - return array_map('basename', glob(__TYPECHO_BACKUP_DIR__ . '/*.dat')); - } - - /** - * 绑定动作 - */ - public function action() - { - $this->user->pass('administrator'); - $this->security->protect(); - - $this->on($this->request->is('do=export'))->export(); - $this->on($this->request->is('do=import'))->import(); - } } diff --git a/var/Widget/Comments/Admin.php b/var/Widget/Comments/Admin.php index 41254155..158ca894 100644 --- a/var/Widget/Comments/Admin.php +++ b/var/Widget/Comments/Admin.php @@ -43,19 +43,6 @@ class Widget_Comments_Admin extends Widget_Abstract_Comments */ private $_total = false; - /** - * 获取当前内容结构 - * - * @return stdClass - */ - 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')); - } - /** * 获取菜单标题 * @@ -86,14 +73,14 @@ class Widget_Comments_Admin extends Widget_Abstract_Comments $this->_currentPage = $this->request->get('page', 1); /** 过滤标题 */ - if (NULL != ($keywords = $this->request->filter('search')->keywords)) { + 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)) { + } elseif (!isset($this->request->cid)) { if ('on' == $this->request->__typecho_all_comments) { Typecho_Cookie::set('__typecho_all_comments', 'on'); } else { @@ -107,9 +94,9 @@ class Widget_Comments_Admin extends Widget_Abstract_Comments } } - if (in_array($this->request->status, array('approved', 'waiting', 'spam'))) { + if (in_array($this->request->status, ['approved', 'waiting', 'spam'])) { $select->where('table.comments.status = ?', $this->request->status); - } else if ('hold' == $this->request->status) { + } elseif ('hold' == $this->request->status) { $select->where('table.comments.status <> ?', 'approved'); } else { $select->where('table.comments.status = ?', 'approved'); @@ -123,9 +110,9 @@ class Widget_Comments_Admin extends Widget_Abstract_Comments $this->_countSql = clone $select; $select->order('table.comments.coid', Typecho_Db::SORT_DESC) - ->page($this->_currentPage, $this->parameter->pageSize); + ->page($this->_currentPage, $this->parameter->pageSize); - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } /** @@ -140,7 +127,20 @@ class Widget_Comments_Admin extends Widget_Abstract_Comments /** 使用盒状分页 */ $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); + $this->_currentPage, $this->parameter->pageSize, $query); $nav->render(_t('«'), _t('»')); } + + /** + * 获取当前内容结构 + * + * @return stdClass + */ + 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), [$this->widget('Widget_Abstract_Contents'), 'filter']); + } } diff --git a/var/Widget/Comments/Archive.php b/var/Widget/Comments/Archive.php index f5219337..25c481e1 100644 --- a/var/Widget/Comments/Archive.php +++ b/var/Widget/Comments/Archive.php @@ -42,15 +42,15 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments * @access private * @var array */ - private $_threadedComments = array(); + private $_threadedComments = []; /** - * _singleCommentOptions - * + * _singleCommentOptions + * * @var mixed * @access private */ - private $_singleCommentOptions = NULL; + private $_singleCommentOptions = null; /** * 构造函数,初始化组件 @@ -61,124 +61,11 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments * @param mixed $params 参数列表 * @return void */ - public function __construct($request, $response, $params = NULL) + public function __construct($request, $response, $params = null) { parent::__construct($request, $response, $params); $this->parameter->setDefault('parentId=0&commentPage=0&commentsNum=0&allowComment=1'); } - - /** - * 评论回调函数 - * - * @access private - * @return void - */ - private function threadedCommentsCallback() - { - $singleCommentOptions = $this->_singleCommentOptions; - if (function_exists('threadedComments')) { - return threadedComments($this, $singleCommentOptions); - } - - $commentClass = ''; - if ($this->authorId) { - if ($this->authorId == $this->ownerId) { - $commentClass .= ' comment-by-author'; - } else { - $commentClass .= ' comment-by-user'; - } - } -?> -<li itemscope itemtype="http://schema.org/UserComments" 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" itemprop="creator" itemscope itemtype="http://schema.org/Person"> - <span itemprop="image"><?php $this->gravatar($singleCommentOptions->avatarSize, $singleCommentOptions->defaultAvatar); ?></span> - <cite class="fn" itemprop="name"><?php $singleCommentOptions->beforeAuthor(); - $this->author(); - $singleCommentOptions->afterAuthor(); ?></cite> - </div> - <div class="comment-meta"> - <a href="<?php $this->permalink(); ?>"><time itemprop="commentTime" datetime="<?php $this->date('c'); ?>"><?php $singleCommentOptions->beforeDate(); - $this->date($singleCommentOptions->dateFormat); - $singleCommentOptions->afterDate(); ?></time></a> - <?php if ('waiting' == $this->status) { ?> - <em class="comment-awaiting-moderation"><?php $singleCommentOptions->commentStatus(); ?></em> - <?php } ?> - </div> - <div class="comment-content" itemprop="commentText"> - <?php $this->content(); ?> - </div> - <div class="comment-reply"> - <?php $this->reply($singleCommentOptions->replyWord); ?> - </div> - <?php if ($this->children) { ?> - <div class="comment-children" itemprop="discusses"> - <?php $this->threadedComments(); ?> - </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; - } /** * 输出文章评论数 @@ -196,7 +83,7 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments $num = intval($this->_total); - echo sprintf(isset($args[$num]) ? $args[$num] : array_pop($args), $num); + echo sprintf($args[$num] ?? array_pop($args), $num); } /** @@ -214,61 +101,61 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments $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; - + ->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')); - + $this->db->fetchAll($select, [$this, 'push']); + /** 需要输出的评论列表 */ - $outputComments = array(); - + $outputComments = []; + /** 如果开启评论回复 */ 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]) + $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) { @@ -276,16 +163,16 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments } 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->length = count($this->stack); - $this->row = $this->length > 0 ? current($this->stack) : array(); + $this->row = $this->length > 0 ? current($this->stack) : []; } - + reset($this->stack); } @@ -299,7 +186,7 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments 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; @@ -310,7 +197,7 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments /** 重载push函数,使用coid作为数组键值,便于索引 */ $this->stack[$value['coid']] = $value; $this->length ++; - + return $value; } @@ -328,10 +215,10 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments public function pageNav($prev = '«', $next = '»', $splitPage = 3, $splitWord = '...', $template = '') { if ($this->options->commentsPageBreak && $this->_total > $this->options->commentsPageSize) { - $default = array( - 'wrapTag' => 'ol', - 'wrapClass' => 'page-navigator' - ); + $default = [ + 'wrapTag' => 'ol', + 'wrapClass' => 'page-navigator' + ]; if (is_string($template)) { parse_str($template, $config); @@ -351,14 +238,171 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments $this->_currentPage, $this->options->commentsPageSize, $query); $nav->setPageHolder('commentPage'); $nav->setAnchor('comments'); - - echo '<' . $template['wrapTag'] . (empty($template['wrapClass']) + + echo '<' . $template['wrapTag'] . (empty($template['wrapClass']) ? '' : ' class="' . $template['wrapClass'] . '"') . '>'; $nav->render($prev, $next, $splitPage, $splitWord, $template); echo '</' . $template['wrapTag'] . '>'; } } + /** + * 列出评论 + * + * @access private + * @param mixed $singleCommentOptions 单个评论自定义选项 + * @return void + */ + public function listComments($singleCommentOptions = null) + { + //初始化一些变量 + $this->_singleCommentOptions = Typecho_Config::factory($singleCommentOptions); + $this->_singleCommentOptions->setDefault([ + 'before' => '<ol class="comment-list">', + 'after' => '</ol>', + 'beforeAuthor' => '', + 'afterAuthor' => '', + 'beforeDate' => '', + 'afterDate' => '', + 'dateFormat' => $this->options->commentDateFormat, + 'replyWord' => _t('回复'), + 'commentStatus' => _t('您的评论正等待审核!'), + 'avatarSize' => 32, + 'defaultAvatar' => null + ]); + $this->pluginHandle()->trigger($plugged)->listComments($this->_singleCommentOptions, $this); + + if (!$plugged) { + if ($this->have()) { + echo $this->_singleCommentOptions->before; + + while ($this->next()) { + $this->threadedCommentsCallback(); + } + + echo $this->_singleCommentOptions->after; + } + } + } + + /** + * 评论回调函数 + * + * @access private + * @return void + */ + private function threadedCommentsCallback() + { + $singleCommentOptions = $this->_singleCommentOptions; + if (function_exists('threadedComments')) { + return threadedComments($this, $singleCommentOptions); + } + + $commentClass = ''; + if ($this->authorId) { + if ($this->authorId == $this->ownerId) { + $commentClass .= ' comment-by-author'; + } else { + $commentClass .= ' comment-by-user'; + } + } + ?> + <li itemscope itemtype="http://schema.org/UserComments" 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" itemprop="creator" itemscope itemtype="http://schema.org/Person"> + <span + itemprop="image"><?php $this->gravatar($singleCommentOptions->avatarSize, $singleCommentOptions->defaultAvatar); ?></span> + <cite class="fn" itemprop="name"><?php $singleCommentOptions->beforeAuthor(); + $this->author(); + $singleCommentOptions->afterAuthor(); ?></cite> + </div> + <div class="comment-meta"> + <a href="<?php $this->permalink(); ?>"> + <time itemprop="commentTime" + datetime="<?php $this->date('c'); ?>"><?php $singleCommentOptions->beforeDate(); + $this->date($singleCommentOptions->dateFormat); + $singleCommentOptions->afterDate(); ?></time> + </a> + <?php if ('waiting' == $this->status) { ?> + <em class="comment-awaiting-moderation"><?php $singleCommentOptions->commentStatus(); ?></em> + <?php } ?> + </div> + <div class="comment-content" itemprop="commentText"> + <?php $this->content(); ?> + </div> + <div class="comment-reply"> + <?php $this->reply($singleCommentOptions->replyWord); ?> + </div> + <?php if ($this->children) { ?> + <div class="comment-children" itemprop="discusses"> + <?php $this->threadedComments(); ?> + </div> + <?php } ?> + </li> + <?php + } + + /** + * 根据深度余数输出 + * + * @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]; + } + + /** + * 重载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 $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>'; + } + } + } + /** * 递归输出评论 * @@ -388,102 +432,10 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments $this->sequence --; } } - - /** - * 列出评论 - * - * @access private - * @param mixed $singleCommentOptions 单个评论自定义选项 - * @return void - */ - public function listComments($singleCommentOptions = NULL) - { - //初始化一些变量 - $this->_singleCommentOptions = Typecho_Config::factory($singleCommentOptions); - $this->_singleCommentOptions->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 - )); - $this->pluginHandle()->trigger($plugged)->listComments($this->_singleCommentOptions, $this); - if (!$plugged) { - if ($this->have()) { - echo $this->_singleCommentOptions->before; - - while ($this->next()) { - $this->threadedCommentsCallback(); - } - - echo $this->_singleCommentOptions->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 @@ -493,12 +445,64 @@ class Widget_Comments_Archive extends Widget_Abstract_Comments 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>'; + '" rel="nofollow"' . ($replyId ? '' : ' style="display:none"') . ' onclick="return TypechoComment.cancelReply();">' . $word . '</a>'; } } } + + /** + * 获取当前评论链接 + * + * @access protected + * @return string + */ + protected function ___permalink() + { + + if ($this->options->commentsPageBreak) { + $pageRow = ['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] : []; + } + + /** + * 是否到达顶层 + * + * @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; + } } diff --git a/var/Widget/Comments/Edit.php b/var/Widget/Comments/Edit.php index f4f1bb68..4173e86a 100644 --- a/var/Widget/Comments/Edit.php +++ b/var/Widget/Comments/Edit.php @@ -19,47 +19,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ 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; - } - /** * 标记为待审核 * @@ -79,12 +38,53 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In /** 设置提示信息 */ $this->widget('Widget_Notice')->set($updateRows > 0 ? _t('评论已经被标记为待审核') : _t('没有评论被标记为待审核'), - $updateRows > 0 ? 'success' : 'notice'); + $updateRows > 0 ? 'success' : 'notice'); /** 返回原网页 */ $this->response->goBack(); } + /** + * 标记评论状态 + * + * @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), [$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(['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'])); + } elseif ('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; + } + /** * 标记为垃圾 * @@ -104,7 +104,7 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In /** 设置提示信息 */ $this->widget('Widget_Notice')->set($updateRows > 0 ? _t('评论已经被标记为垃圾') : _t('没有评论被标记为垃圾'), - $updateRows > 0 ? 'success' : 'notice'); + $updateRows > 0 ? 'success' : 'notice'); /** 返回原网页 */ $this->response->goBack(); @@ -129,7 +129,7 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In /** 设置提示信息 */ $this->widget('Widget_Notice')->set($updateRows > 0 ? _t('评论已经被通过') : _t('没有评论被通过'), - $updateRows > 0 ? 'success' : 'notice'); + $updateRows > 0 ? 'success' : 'notice'); /** 返回原网页 */ $this->response->goBack(); @@ -148,7 +148,7 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In foreach ($comments as $coid) { $comment = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); + ->where('coid = ?', $coid)->limit(1), [$this, 'push']); if ($comment && $this->commentIsWriteable()) { $this->pluginHandle()->delete($comment, $this); @@ -159,33 +159,33 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In /** 更新相关内容的评论数 */ if ('approved' == $comment['status']) { $this->db->query($this->db->update('table.contents') - ->expression('commentsNum', 'commentsNum - 1')->where('cid = ?', $comment['cid'])); + ->expression('commentsNum', 'commentsNum - 1')->where('cid = ?', $comment['cid'])); } - + $this->pluginHandle()->finishDelete($comment, $this); $deleteRows ++; } } - + if ($this->request->isAjax()) { - + if ($deleteRows > 0) { - $this->response->throwJson(array( - 'success' => 1, - 'message' => _t('删除评论成功') - )); + $this->response->throwJson([ + 'success' => 1, + 'message' => _t('删除评论成功') + ]); } else { - $this->response->throwJson(array( - 'success' => 0, - 'message' => _t('删除评论失败') - )); + $this->response->throwJson([ + 'success' => 0, + 'message' => _t('删除评论失败') + ]); } - + } else { /** 设置提示信息 */ $this->widget('Widget_Notice')->set($deleteRows > 0 ? _t('评论已经被删除') : _t('没有评论被删除'), - $deleteRows > 0 ? 'success' : 'notice'); + $deleteRows > 0 ? 'success' : 'notice'); /** 返回原网页 */ $this->response->goBack(); @@ -213,8 +213,8 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In /** 设置提示信息 */ $this->widget('Widget_Notice')->set($deleteRows > 0 ? - _t('所有垃圾评论已经被删除') : _t('没有垃圾评论被删除'), - $deleteRows > 0 ? 'success' : 'notice'); + _t('所有垃圾评论已经被删除') : _t('没有垃圾评论被删除'), + $deleteRows > 0 ? 'success' : 'notice'); /** 返回原网页 */ $this->response->goBack(); @@ -230,21 +230,21 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In { $coid = $this->request->filter('int')->coid; $comment = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); + ->where('coid = ?', $coid)->limit(1), [$this, 'push']); if ($comment && $this->commentIsWriteable()) { - $this->response->throwJson(array( - 'success' => 1, - 'comment' => $comment - )); + $this->response->throwJson([ + 'success' => 1, + 'comment' => $comment + ]); } else { - $this->response->throwJson(array( - 'success' => 0, - 'message' => _t('获取评论失败') - )); + $this->response->throwJson([ + 'success' => 0, + 'message' => _t('获取评论失败') + ]); } } @@ -259,15 +259,15 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In { $coid = $this->request->filter('int')->coid; $commentSelect = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); + ->where('coid = ?', $coid)->limit(1), [$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); @@ -275,24 +275,24 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In $this->update($comment, $this->db->sql()->where('coid = ?', $coid)); $updatedComment = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); + ->where('coid = ?', $coid)->limit(1), [$this, 'push']); $updatedComment['content'] = $this->content; - + /** 评论插件接口 */ $this->pluginHandle()->finishEdit($this); - $this->response->throwJson(array( - 'success' => 1, - 'comment' => $updatedComment - )); + $this->response->throwJson([ + 'success' => 1, + 'comment' => $updatedComment + ]); } - $this->response->throwJson(array( - 'success' => 0, - 'message' => _t('修评论失败') - )); + $this->response->throwJson([ + 'success' => 0, + 'message' => _t('修评论失败') + ]); } - + /** * 回复评论 * @@ -303,26 +303,26 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In { $coid = $this->request->filter('int')->coid; $commentSelect = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); + ->where('coid = ?', $coid)->limit(1), [$this, 'push']); if ($commentSelect && $this->commentIsWriteable()) { - - $comment = array( - 'cid' => $commentSelect['cid'], - 'created' => $this->options->time, - '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' - ); - + + $comment = [ + 'cid' => $commentSelect['cid'], + 'created' => $this->options->time, + '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); @@ -330,22 +330,22 @@ class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_In $commentId = $this->insert($comment); $insertComment = $this->db->fetchRow($this->select() - ->where('coid = ?', $commentId)->limit(1), array($this, 'push')); + ->where('coid = ?', $commentId)->limit(1), [$this, 'push']); $insertComment['content'] = $this->content; - + /** 评论完成接口 */ $this->pluginHandle()->finishComment($this); - $this->response->throwJson(array( - 'success' => 1, - 'comment' => $insertComment - )); + $this->response->throwJson([ + 'success' => 1, + 'comment' => $insertComment + ]); } - $this->response->throwJson(array( - 'success' => 0, - 'message' => _t('回复评论失败') - )); + $this->response->throwJson([ + 'success' => 0, + 'message' => _t('回复评论失败') + ]); } /** diff --git a/var/Widget/Comments/Ping.php b/var/Widget/Comments/Ping.php index bbc3967f..acfa201e 100644 --- a/var/Widget/Comments/Ping.php +++ b/var/Widget/Comments/Ping.php @@ -21,13 +21,13 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; class Widget_Comments_Ping extends Widget_Abstract_Comments { /** - * _customSinglePingCallback - * + * _customSinglePingCallback + * * @var boolean * @access private */ private $_customSinglePingCallback = false; - + /** * 构造函数,初始化组件 * @@ -37,60 +37,17 @@ class Widget_Comments_Ping extends Widget_Abstract_Comments * @param mixed $params 参数列表 * @return void */ - public function __construct($request, $response, $params = NULL) + 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 - } - /** * 输出文章回响数 * @@ -109,8 +66,8 @@ class Widget_Comments_Ping extends Widget_Abstract_Comments } /** - * execute - * + * execute + * * @access public * @return void */ @@ -119,44 +76,87 @@ class Widget_Comments_Ping extends Widget_Abstract_Comments 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')); + $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, [$this, 'push']); } - + /** * 列出回响 - * + * * @access private * @param mixed $singlePingOptions 单个回响自定义选项 * @return void */ - public function listPings($singlePingOptions = NULL) + 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 - )); - + $parsedSinglePingOptions->setDefault([ + '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; } } + + /** + * 回响回调函数 + * + * @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 protected + * @return void + */ + protected function ___parentContent() + { + return $this->parameter->parentContent; + } } diff --git a/var/Widget/Comments/Recent.php b/var/Widget/Comments/Recent.php index 56ce4ce2..d3f74cef 100644 --- a/var/Widget/Comments/Recent.php +++ b/var/Widget/Comments/Recent.php @@ -27,10 +27,10 @@ class Widget_Comments_Recent extends Widget_Abstract_Comments * @param mixed $params 参数列表 * @return void */ - public function __construct($request, $response, $params = NULL) + public function __construct($request, $response, $params = null) { parent::__construct($request, $response, $params); - $this->parameter->setDefault(array('pageSize' => $this->options->commentsListSize, 'parentId' => 0, 'ignoreAuthor' => false)); + $this->parameter->setDefault(['pageSize' => $this->options->commentsListSize, 'parentId' => 0, 'ignoreAuthor' => false]); } /** @@ -41,9 +41,9 @@ class Widget_Comments_Recent extends Widget_Abstract_Comments */ public function execute() { - $select = $this->select()->limit($this->parameter->pageSize) - ->where('table.comments.status = ?', 'approved') - ->order('table.comments.coid', Typecho_Db::SORT_DESC); + $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); @@ -52,12 +52,12 @@ class Widget_Comments_Recent extends Widget_Abstract_Comments if ($this->options->commentsShowCommentOnly) { $select->where('type = ?', 'comment'); } - + /** 忽略作者评论 */ if ($this->parameter->ignoreAuthor) { $select->where('ownerId <> authorId'); } - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } } diff --git a/var/Widget/Contents/Attachment/Admin.php b/var/Widget/Contents/Attachment/Admin.php index e1e57f9b..43981f52 100644 --- a/var/Widget/Contents/Attachment/Admin.php +++ b/var/Widget/Contents/Attachment/Admin.php @@ -52,19 +52,6 @@ class Widget_Contents_Attachment_Admin extends Widget_Abstract_Contents */ 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))); - } - /** * 执行函数 * @@ -85,8 +72,8 @@ class Widget_Contents_Attachment_Admin extends Widget_Abstract_Contents } /** 过滤标题 */ - if (NULL != ($keywords = $this->request->filter('search')->keywords)) { - $args = array(); + if (null != ($keywords = $this->request->filter('search')->keywords)) { + $args = []; $keywordsList = explode(' ', $keywords); $args[] = implode(' OR ', array_fill(0, count($keywordsList), 'table.contents.title LIKE ?')); @@ -94,7 +81,7 @@ class Widget_Contents_Attachment_Admin extends Widget_Abstract_Contents $args[] = '%' . $keyword . '%'; } - call_user_func_array(array($select, 'where'), $args); + call_user_func_array([$select, 'where'], $args); } /** 给计算数目对象赋值,克隆对象 */ @@ -102,9 +89,9 @@ class Widget_Contents_Attachment_Admin extends Widget_Abstract_Contents /** 提交查询 */ $select->order('table.contents.created', Typecho_Db::SORT_DESC) - ->page($this->_currentPage, $this->parameter->pageSize); + ->page($this->_currentPage, $this->parameter->pageSize); - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } /** @@ -119,7 +106,20 @@ class Widget_Contents_Attachment_Admin extends Widget_Abstract_Contents /** 使用盒状分页 */ $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); + $this->_currentPage, $this->parameter->pageSize, $query); $nav->render('«', '»'); } + + /** + * 所属文章 + * + * @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))); + } } diff --git a/var/Widget/Contents/Attachment/Edit.php b/var/Widget/Contents/Attachment/Edit.php index 2e7a4fd7..cd874729 100644 --- a/var/Widget/Contents/Attachment/Edit.php +++ b/var/Widget/Contents/Attachment/Edit.php @@ -21,20 +21,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ 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); - } - /** * 执行函数 * @@ -48,15 +34,15 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen /** 获取文章内容 */ if ((isset($this->request->cid) && 'delete' != $this->request->do - && 'insert' != $this->request->do) || 'update' == $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')); + ->where('table.contents.type = ?', 'attachment') + ->where('table.contents.cid = ?', $this->request->filter('int')->cid) + ->limit(1), [$this, 'push']); if (!$this->have()) { throw new Typecho_Widget_Exception(_t('文件不存在'), 404); - } else if ($this->have() && !$this->allow('edit')) { + } elseif ($this->have() && !$this->allow('edit')) { throw new Typecho_Widget_Exception(_t('没有编辑权限'), 403); } } @@ -91,10 +77,10 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen public function slugExists($slug) { $select = $this->db->select() - ->from('table.contents') - ->where('type = ?', 'attachment') - ->where('slug = ?', Typecho_Common::slugName($slug)) - ->limit(1); + ->from('table.contents') + ->where('type = ?', 'attachment') + ->where('slug = ?', Typecho_Common::slugName($slug)) + ->limit(1); if ($this->request->cid) { $select->where('cid <> ?', $this->request->cid); @@ -104,58 +90,6 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen return $attachment ? false : true; } - /** - * 生成表单 - * - * @access public - * @return Typecho_Widget_Helper_Form_Element - */ - public function form() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/contents-attachment-edit'), - 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', 'btn primary'); - $delete = new Typecho_Widget_Helper_Layout('a', array( - 'href' => $this->security->getIndex('/action/contents-attachment-edit?do=delete&cid=' . $this->cid), - '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; - } - /** * 更新文件 * @@ -189,21 +123,87 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen $this->db->fetchRow($this->select() ->where('table.contents.type = ?', 'attachment') ->where('table.contents.cid = ?', $cid) - ->limit(1), array($this, 'push')); + ->limit(1), [$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'); + _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)); + $this->getPageOffsetQuery($cid, $this->status), $this->options->adminUrl)); + } + + /** + * 生成表单 + * + * @access public + * @return Typecho_Widget_Helper_Form_Element + */ + public function form() + { + /** 构建表格 */ + $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/contents-attachment-edit'), + 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', 'btn primary'); + $delete = new Typecho_Widget_Helper_Layout('a', [ + 'href' => $this->security->getIndex('/action/contents-attachment-edit?do=delete&cid=' . $this->cid), + 'class' => 'operate-delete', + 'lang' => _t('你确认删除文件 %s 吗?', $this->attachment->name) + ]); + $submit->container($delete->html(_t('删除文件'))); + $form->addItem($submit); + + $name->addRule('required', _t('必须填写文件标题')); + $name->addRule([$this, 'nameToSlug'], _t('文件标题无法被转换为缩略名')); + $slug->addRule([$this, 'slugExists'], _t('缩略名已经存在')); + + return $form; + } + + /** + * 获取页面偏移的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); } /** @@ -225,7 +225,7 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen $row = $this->db->fetchRow($this->select() ->where('table.contents.type = ?', 'attachment') ->where('table.contents.cid = ?', $post) - ->limit(1), array($this, 'push')); + ->limit(1), [$this, 'push']); if ($this->isWriteable(clone $condition) && $this->delete($condition)) { /** 删除文件 */ @@ -245,12 +245,12 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen } if ($this->request->isAjax()) { - $this->response->throwJson($deleteCount > 0 ? array('code' => 200, 'message' => _t('文件已经被删除')) - : array('code' => 500, 'message' => _t('没有文件被删除'))); + $this->response->throwJson($deleteCount > 0 ? ['code' => 200, 'message' => _t('文件已经被删除')] + : ['code' => 500, 'message' => _t('没有文件被删除')]); } else { /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('文件已经被删除') : _t('没有文件被删除'), - $deleteCount > 0 ? 'success' : 'notice'); + $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)); @@ -258,8 +258,8 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen } /** - * clearAttachment - * + * clearAttachment + * * @access public * @return void */ @@ -274,16 +274,16 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen ->where('type = ? AND parent = ?', 'attachment', 0) ->page($page, 100)), 'cid'); $page ++; - + foreach ($posts as $post) { // 删除插件接口 $this->pluginHandle()->delete($post, $this); $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')); + ->where('table.contents.type = ?', 'attachment') + ->where('table.contents.cid = ?', $post) + ->limit(1), [$this, 'push']); if ($this->isWriteable(clone $condition) && $this->delete($condition)) { /** 删除文件 */ @@ -291,7 +291,7 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen /** 删除评论 */ $this->db->query($this->db->delete('table.comments') - ->where('cid = ?', $post)); + ->where('cid = ?', $post)); $status = $this->status; @@ -306,7 +306,7 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen } while (count($posts) == 100); /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('未归档文件已经被清理') : _t('没有未归档文件被清理'), + $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('未归档文件已经被清理') : _t('没有未归档文件被清理'), $deleteCount > 0 ? 'success' : 'notice'); /** 返回原网页 */ diff --git a/var/Widget/Contents/Attachment/Related.php b/var/Widget/Contents/Attachment/Related.php index 61f84b72..08647fa6 100644 --- a/var/Widget/Contents/Attachment/Related.php +++ b/var/Widget/Contents/Attachment/Related.php @@ -52,6 +52,6 @@ class Widget_Contents_Attachment_Related extends Widget_Abstract_Contents $select->offset($this->parameter->offset); } - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } } diff --git a/var/Widget/Contents/Attachment/Unattached.php b/var/Widget/Contents/Attachment/Unattached.php index 768bb430..74d5751f 100644 --- a/var/Widget/Contents/Attachment/Unattached.php +++ b/var/Widget/Contents/Attachment/Unattached.php @@ -31,13 +31,13 @@ class Widget_Contents_Attachment_Unattached extends Widget_Abstract_Contents /** 构建基础查询 */ $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')); + $this->db->fetchAll($select, [$this, 'push']); } } diff --git a/var/Widget/Contents/Page/Admin.php b/var/Widget/Contents/Page/Admin.php index e65abfc6..4e2f5699 100644 --- a/var/Widget/Contents/Page/Admin.php +++ b/var/Widget/Contents/Page/Admin.php @@ -32,8 +32,8 @@ class Widget_Contents_Page_Admin extends Widget_Contents_Post_Admin $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(); + if (null != ($keywords = $this->request->keywords)) { + $args = []; $keywordsList = explode(' ', $keywords); $args[] = implode(' OR ', array_fill(0, count($keywordsList), 'table.contents.title LIKE ?')); @@ -41,12 +41,12 @@ class Widget_Contents_Page_Admin extends Widget_Contents_Post_Admin $args[] = '%' . Typecho_Common::filterSearchQuery($keyword) . '%'; } - call_user_func_array(array($select, 'where'), $args); + call_user_func_array([$select, 'where'], $args); } /** 提交查询 */ $select->order('table.contents.order', Typecho_Db::SORT_ASC); - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } } diff --git a/var/Widget/Contents/Page/Edit.php b/var/Widget/Contents/Page/Edit.php index 730ee71b..4027e410 100644 --- a/var/Widget/Contents/Page/Edit.php +++ b/var/Widget/Contents/Page/Edit.php @@ -22,13 +22,13 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Widget_Interface_Do { /** - * 自定义字段的hook名称 - * + * 自定义字段的hook名称 + * * @var string * @access protected */ protected $themeCustomFieldsHook = 'themePageFields'; - + /** * 执行函数 * @@ -41,12 +41,12 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid $this->user->pass('editor'); /** 获取文章内容 */ - if (!empty($this->request->cid) && 'delete' != $this->request->do + 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')); + ->where('table.contents.type = ? OR table.contents.type = ?', 'page', 'page_draft') + ->where('table.contents.cid = ?', $this->request->filter('int')->cid) + ->limit(1), [$this, 'push']); if ('page_draft' == $this->status && $this->parent) { $this->response->redirect(Typecho_Common::url('write-page.php?cid=' . $this->parent, $this->options->adminUrl)); @@ -54,7 +54,7 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid if (!$this->have()) { throw new Typecho_Widget_Exception(_t('页面不存在'), 404); - } else if ($this->have() && !$this->allow('edit')) { + } elseif ($this->have() && !$this->allow('edit')) { throw new Typecho_Widget_Exception(_t('没有编辑权限'), 403); } } @@ -81,7 +81,7 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid $contents = $this->pluginHandle()->write($contents, $this); - if ($this->request->is('do=publish')) { + if ($this->request->is('do=publish')) { /** 重新发布已经存在的文章 */ $contents['type'] = 'page'; $this->publish($contents); @@ -113,12 +113,12 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid if ($this->request->isAjax()) { $created = new Typecho_Date($this->options->time); - $this->response->throwJson(array( - 'success' => 1, - 'time' => $created->format('H:i:s A'), - 'cid' => $this->cid, - 'draftId' => $this->draft['cid'] - )); + $this->response->throwJson([ + 'success' => 1, + 'time' => $created->format('H:i:s A'), + 'cid' => $this->cid, + 'draftId' => $this->draft['cid'] + ]); } else { /** 设置提示信息 */ $this->widget('Widget_Notice')->set(_t('草稿 "%s" 已经被保存', $this->title), 'success'); @@ -138,33 +138,33 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid public function markPage() { $status = $this->request->get('status'); - $statusList = array( - 'publish' => _t('公开'), - 'hidden' => _t('隐藏') - ); + $statusList = [ + 'publish' => _t('公开'), + 'hidden' => _t('隐藏') + ]; if (!isset($statusList[$status])) { $this->response->goBack(); } $pages = $this->request->filter('int')->getArray('cid'); - $markCount = 0; + $markCount = 0; foreach ($pages as $page) { // 标记插件接口 $this->pluginHandle()->mark($status, $page, $this); $condition = $this->db->sql()->where('cid = ?', $page); - if ($this->db->query($condition->update('table.contents')->rows(array('status' => $status)))) { + if ($this->db->query($condition->update('table.contents')->rows(['status' => $status]))) { // 处理草稿 $draft = $this->db->fetchRow($this->db->select('cid') ->from('table.contents') ->where('table.contents.parent = ? AND table.contents.type = ?', $page, 'page_draft') - ->limit(1)); + ->limit(1)); if (!empty($draft)) { - $this->db->query($this->db->update('table.contents')->rows(array('status' => $status)) + $this->db->query($this->db->update('table.contents')->rows(['status' => $status]) ->where('cid = ?', $draft['cid'])); } @@ -179,7 +179,7 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid /** 设置提示信息 */ $this->widget('Widget_Notice')->set($markCount > 0 ? _t('页面已经被标记为<strong>%s</strong>', $statusList[$status]) : _t('没有页面被标记'), - $markCount > 0 ? 'success' : 'notice'); + $markCount > 0 ? 'success' : 'notice'); /** 返回原网页 */ $this->response->goBack(); @@ -211,7 +211,7 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid /** 解除首页关联 */ if ($this->options->frontPage == 'page:' . $page) { $this->db->query($this->db->update('table.options') - ->rows(array('value' => 'recent')) + ->rows(['value' => 'recent']) ->where('name = ?', 'frontPage')); } @@ -239,15 +239,15 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid /** 设置提示信息 */ $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('页面已经被删除') : _t('没有页面被删除'), - $deleteCount > 0 ? 'success' : 'notice'); + $deleteCount > 0 ? 'success' : 'notice'); /** 返回原网页 */ $this->response->goBack(); } - + /** * 删除页面所属草稿 - * + * * @access public * @return void */ @@ -273,8 +273,8 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid /** 设置提示信息 */ $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('草稿已经被删除') : _t('没有草稿被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - + $deleteCount > 0 ? 'success' : 'notice'); + /** 返回原网页 */ $this->response->goBack(); } @@ -291,8 +291,8 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid if ($pages) { foreach ($pages as $sort => $cid) { - $this->db->query($this->db->update('table.contents')->rows(array('order' => $sort + 1)) - ->where('cid = ?', $cid)); + $this->db->query($this->db->update('table.contents')->rows(['order' => $sort + 1]) + ->where('cid = ?', $cid)); } } @@ -300,7 +300,7 @@ class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Wid /** 转向原页 */ $this->response->goBack(); } else { - $this->response->throwJson(array('success' => 1, 'message' => _t('页面排序已经完成'))); + $this->response->throwJson(['success' => 1, 'message' => _t('页面排序已经完成')]); } } diff --git a/var/Widget/Contents/Page/List.php b/var/Widget/Contents/Page/List.php index a6e5589b..199c1781 100644 --- a/var/Widget/Contents/Page/List.php +++ b/var/Widget/Contents/Page/List.php @@ -30,9 +30,9 @@ class Widget_Contents_Page_List extends Widget_Abstract_Contents public function execute() { $select = $this->select()->where('table.contents.type = ?', 'page') - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.created < ?', $this->options->time) - ->order('table.contents.order', Typecho_Db::SORT_ASC); + ->where('table.contents.status = ?', 'publish') + ->where('table.contents.created < ?', $this->options->time) + ->order('table.contents.order', Typecho_Db::SORT_ASC); //去掉自定义首页 $frontPage = explode(':', $this->options->frontPage); @@ -40,6 +40,6 @@ class Widget_Contents_Page_List extends Widget_Abstract_Contents $select->where('table.contents.cid <> ?', $frontPage[1]); } - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } } diff --git a/var/Widget/Contents/Post/Admin.php b/var/Widget/Contents/Post/Admin.php index 07aca7d7..4dae5a87 100644 --- a/var/Widget/Contents/Post/Admin.php +++ b/var/Widget/Contents/Post/Admin.php @@ -44,32 +44,6 @@ class Widget_Contents_Post_Admin extends Widget_Abstract_Contents */ private $_currentPage; - /** - * 当前文章的草稿 - * - * @access protected - * @return bool - */ - protected function ___hasSaved() - { - if (in_array($this->type, array('post_draft', 'page_draft'))) { - return true; - } - - $savedPost = $this->db->fetchRow($this->db->select('cid', 'modified', 'status') - ->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; - } - /** * 获取菜单标题 * @@ -142,7 +116,7 @@ class Widget_Contents_Post_Admin extends Widget_Abstract_Contents /** 按状态查询 */ if ('draft' == $this->request->status) { $select->where('table.contents.type = ?', 'post_draft'); - } else if ('waiting' == $this->request->status) { + } elseif ('waiting' == $this->request->status) { $select->where('(table.contents.type = ? OR table.contents.type = ?) AND table.contents.status = ?', 'post', 'post_draft', 'waiting'); } else { @@ -151,14 +125,14 @@ class Widget_Contents_Post_Admin extends Widget_Abstract_Contents } /** 过滤分类 */ - if (NULL != ($category = $this->request->category)) { + if (null != ($category = $this->request->category)) { $select->join('table.relationships', 'table.contents.cid = table.relationships.cid') - ->where('table.relationships.mid = ?', $category); + ->where('table.relationships.mid = ?', $category); } /** 过滤标题 */ - if (NULL != ($keywords = $this->request->filter('search')->keywords)) { - $args = array(); + if (null != ($keywords = $this->request->filter('search')->keywords)) { + $args = []; $keywordsList = explode(' ', $keywords); $args[] = implode(' OR ', array_fill(0, count($keywordsList), 'table.contents.title LIKE ?')); @@ -166,7 +140,7 @@ class Widget_Contents_Post_Admin extends Widget_Abstract_Contents $args[] = '%' . $keyword . '%'; } - call_user_func_array(array($select, 'where'), $args); + call_user_func_array([$select, 'where'], $args); } /** 给计算数目对象赋值,克隆对象 */ @@ -174,9 +148,9 @@ class Widget_Contents_Post_Admin extends Widget_Abstract_Contents /** 提交查询 */ $select->order('table.contents.cid', Typecho_Db::SORT_DESC) - ->page($this->_currentPage, $this->parameter->pageSize); + ->page($this->_currentPage, $this->parameter->pageSize); - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } /** @@ -191,8 +165,34 @@ class Widget_Contents_Post_Admin extends Widget_Abstract_Contents /** 使用盒状分页 */ $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); + $this->_currentPage, $this->parameter->pageSize, $query); $nav->render('«', '»'); } + + /** + * 当前文章的草稿 + * + * @access protected + * @return bool + */ + protected function ___hasSaved() + { + if (in_array($this->type, ['post_draft', 'page_draft'])) { + return true; + } + + $savedPost = $this->db->fetchRow($this->db->select('cid', 'modified', 'status') + ->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; + } } diff --git a/var/Widget/Contents/Post/Date.php b/var/Widget/Contents/Post/Date.php index 8abb0059..c56d1a2f 100644 --- a/var/Widget/Contents/Post/Date.php +++ b/var/Widget/Contents/Post/Date.php @@ -13,7 +13,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; /** * 按日期归档列表组件 * - * @fixme 交给缓存 * @author qining * @category typecho * @package Widget @@ -44,7 +43,7 @@ class Widget_Contents_Post_Date extends Typecho_Widget * @param mixed $response response对象 * @param mixed $params 参数列表 */ - public function __construct($request, $response, $params = NULL) + public function __construct($request, $response, $params = null) { parent::__construct($request, $response, $params); @@ -67,13 +66,13 @@ class Widget_Contents_Post_Date extends Typecho_Widget $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->time) - ->order('table.contents.created', Typecho_Db::SORT_DESC)); + ->where('type = ?', 'post') + ->where('table.contents.status = ?', 'publish') + ->where('table.contents.created < ?', $this->options->time) + ->order('table.contents.created', Typecho_Db::SORT_DESC)); $offset = $this->options->timezone - $this->options->serverTimezone; - $result = array(); + $result = []; while ($post = $this->db->fetchRow($resource)) { $timeStamp = $post['created'] + $offset; $date = date($this->parameter->format, $timeStamp); diff --git a/var/Widget/Contents/Post/Edit.php b/var/Widget/Contents/Post/Edit.php index 51e1d026..a2967a9d 100644 --- a/var/Widget/Contents/Post/Edit.php +++ b/var/Widget/Contents/Post/Edit.php @@ -22,355 +22,13 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widget_Interface_Do { /** - * 自定义字段的hook名称 - * + * 自定义字段的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(); - } - - /** - * 当前文章的草稿 - * - * @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 array - */ - protected function getFields() - { - $fields = array(); - $fieldNames = $this->request->getArray('fieldNames'); - - if (!empty($fieldNames)) { - $data = array( - 'fieldNames' => $this->request->getArray('fieldNames'), - 'fieldTypes' => $this->request->getArray('fieldTypes'), - 'fieldValues' => $this->request->getArray('fieldValues') - ); - foreach ($data['fieldNames'] as $key => $val) { - $val = trim($val); - - if (0 == strlen($val)) { - continue; - } - - $fields[$val] = array($data['fieldTypes'][$key], $data['fieldValues'][$key]); - } - } - - $customFields = $this->request->getArray('fields'); - if (!empty($customFields)) { - $fields = array_merge($fields, $customFields); - } - - return $fields; - } - - /** - * 根据提交值获取created字段值 - * - * @access protected - * @return integer - */ - protected function getCreated() - { - $created = $this->options->time; - if (!empty($this->request->created)) { - $created = $this->request->created; - } else if (!empty($this->request->date)) { - $dstOffset = !empty($this->request->dst) ? $this->request->dst : 0; - $timezoneSymbol = $this->options->timezone >= 0 ? '+' : '-'; - $timezoneOffset = abs($this->options->timezone); - $timezone = $timezoneSymbol . str_pad($timezoneOffset / 3600, 2, '0', STR_PAD_LEFT) . ':00'; - list ($date, $time) = explode(' ', $this->request->date); - - $created = strtotime("{$date}T{$time}{$timezone}") - $dstOffset; - } 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->have() && $this->created > 0) { - //如果是修改文章 - $created = $this->created; - } else if ($this->request->is('do=save')) { - // 如果是草稿而且没有任何输入则保持原状 - $created = 0; - } - - return $created; - } - - /** - * 同步附件 - * - * @access protected - * @param integer $cid 内容id - * @return void - */ - protected function attach($cid) - { - $attachments = $this->request->getArray('attachment'); - if (!empty($attachments)) { - 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 $cid 文章id - * @param string $status 状态 - * @return string - */ - protected function getPageOffsetQuery($cid, $status = NULL) - { - return 'page=' . $this->getPageOffset('cid', $cid, '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) { - $cid = $this->draft['cid']; - $this->deleteDraft($cid); - $this->deleteFields($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); - } - } - /** * 执行函数 * @@ -384,9 +42,9 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg /** 获取文章内容 */ 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')); + ->where('table.contents.type = ? OR table.contents.type = ?', 'post', 'post_draft') + ->where('table.contents.cid = ?', $this->request->filter('int')->cid) + ->limit(1), [$this, 'push']); if ('post_draft' == $this->type && $this->parent) { $this->response->redirect(Typecho_Common::url('write-post.php?cid=' . $this->parent, $this->options->adminUrl)); @@ -394,63 +52,12 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg if (!$this->have()) { throw new Typecho_Widget_Exception(_t('文章不存在'), 404); - } else if ($this->have() && !$this->allow('edit')) { + } elseif ($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->time + $this->options->timezone - $this->options->serverTimezone); - } - } - /** * 获取文章权限 * @@ -469,13 +76,64 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg } else { $permission = 'allow' . ucfirst(strtolower($permission)); $optionPermission = 'default' . ucfirst($permission); - $allow &= (isset($this->{$permission}) ? $this->{$permission} : $this->options->{$optionPermission}); + $allow &= ($this->{$permission} ?? $this->options->{$optionPermission}); } } return $allow; } + /** + * 过滤堆栈 + * + * @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'), [$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->time + $this->options->timezone - $this->options->serverTimezone); + } + } + /** * 获取网页标题 * @@ -487,15 +145,47 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg return _t('编辑 %s', $this->title); } + /** + * getFieldItems + * + * @access public + * @return void + */ + public function getFieldItems() + { + $fields = []; + + 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; + } + /** * getDefaultFieldItems - * + * * @access public * @return array */ public function getDefaultFieldItems() { - $defaultFields = array(); + $defaultFields = []; $configFile = $this->options->themeFile($this->options->theme, 'functions.php'); $layout = new Typecho_Widget_Helper_Layout(); $fields = new Typecho_Config(); @@ -508,9 +198,9 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg if (file_exists($configFile)) { require_once $configFile; - + if (function_exists('themeFields')) { - themeFields($layout); + themeFields($layout); } if (function_exists($this->themeCustomFieldsHook)) { @@ -518,7 +208,7 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg } } - $items = $layout->getItems(); + $items = $layout->getItems(); foreach ($items as $item) { if ($item instanceof Typecho_Widget_Helper_Form_Element) { $name = $item->input->getAttribute('name'); @@ -548,177 +238,14 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg foreach ($elements as $el) { $div->addItem($el); } - - $defaultFields[$name] = array($item->label, $div); + + $defaultFields[$name] = [$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 $beforeCount 是否参与计数 - * @param boolean $afterCount 是否参与计数 - * @return string - */ - public function setTags($cid, $tags, $beforeCount = true, $afterCount = true) - { - $tags = str_replace(',', ',', $tags); - $tags = array_unique(array_map('trim', explode(',', $tags))); - $tags = array_filter($tags, array('Typecho_Validate', 'xssCheck')); - - /** 取出已有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) { - if (0 == strlen($tag)) { - continue; - } - - $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) { - if (0 == strlen($tag)) { - continue; - } - - $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 $beforeCount 是否参与计数 - * @param boolean $afterCount 是否参与计数 - * @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)); - } - } - } - } - /** * 发布文章 * @@ -754,8 +281,8 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg /** 设置提示信息 */ $this->widget('Widget_Notice')->set('post' == $this->type ? - _t('文章 "<a href="%s">%s</a>" 已经发布', $this->permalink, $this->title) : - _t('文章 "%s" 等待审核', $this->title), 'success'); + _t('文章 "<a href="%s">%s</a>" 已经发布', $this->permalink, $this->title) : + _t('文章 "%s" 等待审核', $this->title), 'success'); /** 设置高亮 */ $this->widget('Widget_Notice')->highlight($this->theId); @@ -778,12 +305,12 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg if ($this->request->isAjax()) { $created = new Typecho_Date(); - $this->response->throwJson(array( - 'success' => 1, - 'time' => $created->format('H:i:s A'), - 'cid' => $this->cid, - 'draftId' => $this->draft['cid'] - )); + $this->response->throwJson([ + 'success' => 1, + 'time' => $created->format('H:i:s A'), + 'cid' => $this->cid, + 'draftId' => $this->draft['cid'] + ]); } else { /** 设置提示信息 */ $this->widget('Widget_Notice')->set(_t('草稿 "%s" 已经被保存', $this->title), 'success'); @@ -794,6 +321,416 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg } } + /** + * 根据提交值获取created字段值 + * + * @access protected + * @return integer + */ + protected function getCreated() + { + $created = $this->options->time; + if (!empty($this->request->created)) { + $created = $this->request->created; + } elseif (!empty($this->request->date)) { + $dstOffset = !empty($this->request->dst) ? $this->request->dst : 0; + $timezoneSymbol = $this->options->timezone >= 0 ? '+' : '-'; + $timezoneOffset = abs($this->options->timezone); + $timezone = $timezoneSymbol . str_pad($timezoneOffset / 3600, 2, '0', STR_PAD_LEFT) . ':00'; + [$date, $time] = explode(' ', $this->request->date); + + $created = strtotime("{$date}T{$time}{$timezone}") - $dstOffset; + } elseif (!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; + } elseif ($this->have() && $this->created > 0) { + //如果是修改文章 + $created = $this->created; + } elseif ($this->request->is('do=save')) { + // 如果是草稿而且没有任何输入则保持原状 + $created = 0; + } + + return $created; + } + + /** + * 发布内容 + * + * @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'; + } elseif ('password' == $contents['visibility'] || !in_array($contents['visibility'], ['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) { + $cid = $this->draft['cid']; + $this->deleteDraft($cid); + $this->deleteFields($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'] : [$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), [$this, 'push']); + } + } + + /** + * 删除草稿 + * + * @access protected + * @param integer $cid 草稿id + * @return void + */ + protected function deleteDraft($cid) + { + $this->delete($this->db->sql()->where('cid = ?', $cid)); + + /** 删除草稿分类 */ + $this->setCategories($cid, [], false, false); + + /** 删除标签 */ + $this->setTags($cid, null, false, false); + } + + /** + * 设置分类 + * + * @access public + * @param integer $cid 内容id + * @param array $categories 分类id的集合数组 + * @param boolean $beforeCount 是否参与计数 + * @param boolean $afterCount 是否参与计数 + * @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([ + 'mid' => $category, + 'cid' => $cid + ])); + + if ($afterCount) { + $this->db->query($this->db->update('table.metas') + ->expression('count', 'count + 1') + ->where('mid = ?', $category)); + } + } + } + } + + /** + * 设置内容标签 + * + * @access public + * @param integer $cid + * @param string $tags + * @param boolean $beforeCount 是否参与计数 + * @param boolean $afterCount 是否参与计数 + * @return string + */ + public function setTags($cid, $tags, $beforeCount = true, $afterCount = true) + { + $tags = str_replace(',', ',', $tags); + $tags = array_unique(array_map('trim', explode(',', $tags))); + $tags = array_filter($tags, ['Typecho_Validate', 'xssCheck']); + + /** 取出已有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) { + if (0 == strlen($tag)) { + continue; + } + + $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) { + if (0 == strlen($tag)) { + continue; + } + + $this->db->query($this->db->insert('table.relationships') + ->rows([ + 'mid' => $tag, + 'cid' => $cid + ])); + + if ($afterCount) { + $this->db->query($this->db->update('table.metas') + ->expression('count', 'count + 1') + ->where('mid = ?', $tag)); + } + } + } + } + + /** + * 同步附件 + * + * @access protected + * @param integer $cid 内容id + * @return void + */ + protected function attach($cid) + { + $attachments = $this->request->getArray('attachment'); + if (!empty($attachments)) { + foreach ($attachments as $key => $attachment) { + $this->db->query($this->db->update('table.contents')->rows([ + 'parent' => $cid, 'status' => 'publish', + 'order' => $key + 1 + ])->where('cid = ? AND type = ?', $attachment, 'attachment')); + } + } + } + + /** + * getFields + * + * @access protected + * @return array + */ + protected function getFields() + { + $fields = []; + $fieldNames = $this->request->getArray('fieldNames'); + + if (!empty($fieldNames)) { + $data = [ + 'fieldNames' => $this->request->getArray('fieldNames'), + 'fieldTypes' => $this->request->getArray('fieldTypes'), + 'fieldValues' => $this->request->getArray('fieldValues') + ]; + foreach ($data['fieldNames'] as $key => $val) { + $val = trim($val); + + if (0 == strlen($val)) { + continue; + } + + $fields[$val] = [$data['fieldTypes'][$key], $data['fieldValues'][$key]]; + } + } + + $customFields = $this->request->getArray('fields'); + if (!empty($customFields)) { + $fields = array_merge($fields, $customFields); + } + + return $fields; + } + + /** + * 获取页面偏移的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, 'post', $status, + 'on' == $this->request->__typecho_all_posts ? 0 : $this->user->uid); + } + + /** + * 保存内容 + * + * @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'; + } elseif ('password' == $contents['visibility'] || !in_array($contents['visibility'], ['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), [$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'] : [$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); + } + } + /** * 标记文章 * @@ -803,19 +740,19 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg public function markPost() { $status = $this->request->get('status'); - $statusList = array( - 'publish' => _t('公开'), - 'private' => _t('私密'), - 'hidden' => _t('隐藏'), - 'waiting' => _t('待审核') - ); + $statusList = [ + 'publish' => _t('公开'), + 'private' => _t('私密'), + 'hidden' => _t('隐藏'), + 'waiting' => _t('待审核') + ]; if (!isset($statusList[$status])) { $this->response->goBack(); } $posts = $this->request->filter('int')->getArray('cid'); - $markCount = 0; + $markCount = 0; foreach ($posts as $post) { // 标记插件接口 @@ -826,18 +763,18 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg ->from('table.contents')->where('cid = ? AND (type = ? OR type = ?)', $post, 'post', 'post_draft')); if ($this->isWriteable(clone $condition) && - count((array) $postObject)) { + count((array)$postObject)) { /** 标记状态 */ - $this->db->query($condition->update('table.contents')->rows(array('status' => $status))); + $this->db->query($condition->update('table.contents')->rows(['status' => $status])); // 刷新Metas if ($postObject->type == 'post') { - $op = NULL; + $op = null; if ($status == 'publish' && $postObject->status != 'publish') { $op = '+'; - } else if ($status != 'publish' && $postObject->status == 'publish') { + } elseif ($status != 'publish' && $postObject->status == 'publish') { $op = '-'; } @@ -856,10 +793,10 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg ->from('table.contents') ->where('table.contents.parent = ? AND table.contents.type = ?', $post, 'post_draft') - ->limit(1)); + ->limit(1)); if (!empty($draft)) { - $this->db->query($this->db->update('table.contents')->rows(array('status' => $status)) + $this->db->query($this->db->update('table.contents')->rows(['status' => $status]) ->where('cid = ?', $draft['cid'])); } @@ -874,7 +811,7 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg /** 设置提示信息 */ $this->widget('Widget_Notice')->set($markCount > 0 ? _t('文章已经被标记为<strong>%s</strong>', $statusList[$status]) : _t('没有文章被标记'), - $markCount > 0 ? 'success' : 'notice'); + $markCount > 0 ? 'success' : 'notice'); /** 返回原网页 */ $this->response->goBack(); @@ -900,15 +837,15 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg ->from('table.contents')->where('cid = ? AND (type = ? OR type = ?)', $post, 'post', 'post_draft')); if ($this->isWriteable(clone $condition) && - count((array) $postObject) && + count((array)$postObject) && $this->delete($condition)) { /** 删除分类 */ - $this->setCategories($post, array(), 'publish' == $postObject->status + $this->setCategories($post, [], 'publish' == $postObject->status && 'post' == $postObject->type); /** 删除标签 */ - $this->setTags($post, NULL, 'publish' == $postObject->status + $this->setTags($post, null, 'publish' == $postObject->status && 'post' == $postObject->type); /** 删除评论 */ @@ -949,15 +886,28 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg /** 设置提示信息 */ $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('文章已经被删除') : _t('没有文章被删除'), - $deleteCount > 0 ? 'success' : 'notice'); + $deleteCount > 0 ? 'success' : 'notice'); /** 返回原网页 */ $this->response->goBack(); } - + + /** + * 取消附件关联 + * + * @access protected + * @param integer $cid 内容id + * @return void + */ + protected function unAttach($cid) + { + $this->db->query($this->db->update('table.contents')->rows(['parent' => 0, 'status' => 'publish']) + ->where('parent = ? AND type = ?', $cid, 'attachment')); + } + /** * 删除文章所属草稿 - * + * * @access public * @return void */ @@ -983,8 +933,8 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg /** 设置提示信息 */ $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('草稿已经被删除') : _t('没有草稿被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - + $deleteCount > 0 ? 'success' : 'notice'); + /** 返回原网页 */ $this->response->goBack(); } @@ -1005,5 +955,57 @@ class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widg $this->response->redirect($this->options->adminUrl); } + + /** + * 将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'), [$this->widget('Widget_Abstract_Metas'), 'filter']); + } + + return []; + } + + /** + * 获取当前时间 + * + * @access protected + * @return Typecho_Date + */ + protected function ___date() + { + return new Typecho_Date(); + } + + /** + * 当前文章的草稿 + * + * @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), [$this->widget('Widget_Abstract_Contents'), 'filter']); + } + } + + return null; + } } diff --git a/var/Widget/Contents/Post/Recent.php b/var/Widget/Contents/Post/Recent.php index 0422da20..c401c5ac 100644 --- a/var/Widget/Contents/Post/Recent.php +++ b/var/Widget/Contents/Post/Recent.php @@ -28,13 +28,13 @@ class Widget_Contents_Post_Recent extends Widget_Abstract_Contents */ public function execute() { - $this->parameter->setDefault(array('pageSize' => $this->options->postsListSize)); + $this->parameter->setDefault(['pageSize' => $this->options->postsListSize]); $this->db->fetchAll($this->select() - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.created < ?', $this->options->time) - ->where('table.contents.type = ?', 'post') - ->order('table.contents.created', Typecho_Db::SORT_DESC) - ->limit($this->parameter->pageSize), array($this, 'push')); + ->where('table.contents.status = ?', 'publish') + ->where('table.contents.created < ?', $this->options->time) + ->where('table.contents.type = ?', 'post') + ->order('table.contents.created', Typecho_Db::SORT_DESC) + ->limit($this->parameter->pageSize), [$this, 'push']); } } diff --git a/var/Widget/Contents/Related.php b/var/Widget/Contents/Related.php index 66a5c016..1f21f950 100644 --- a/var/Widget/Contents/Related.php +++ b/var/Widget/Contents/Related.php @@ -21,20 +21,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ 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'); - } - /** * 执行函数,初始化数据 * @@ -48,15 +34,29 @@ class Widget_Contents_Related extends Widget_Abstract_Contents 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->time) - ->where('table.contents.type = ?', $this->parameter->type) - ->order('table.contents.created', Typecho_Db::SORT_DESC) - ->limit($this->parameter->limit), array($this, 'push')); + ->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->time) + ->where('table.contents.type = ?', $this->parameter->type) + ->order('table.contents.created', Typecho_Db::SORT_DESC) + ->limit($this->parameter->limit), [$this, 'push']); } } + + /** + * 获取查询对象 + * + * @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'); + } } diff --git a/var/Widget/Contents/Related/Author.php b/var/Widget/Contents/Related/Author.php index a876764c..b1a05b7a 100644 --- a/var/Widget/Contents/Related/Author.php +++ b/var/Widget/Contents/Related/Author.php @@ -33,14 +33,14 @@ class Widget_Contents_Related_Author extends Widget_Abstract_Contents 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->time) - ->where('table.contents.type = ?', $this->parameter->type) - ->order('table.contents.created', Typecho_Db::SORT_DESC) - ->limit($this->parameter->limit), array($this, 'push')); + ->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->time) + ->where('table.contents.type = ?', $this->parameter->type) + ->order('table.contents.created', Typecho_Db::SORT_DESC) + ->limit($this->parameter->limit), [$this, 'push']); } } } diff --git a/var/Widget/Do.php b/var/Widget/Do.php index e5f3ca29..3bae6f8f 100644 --- a/var/Widget/Do.php +++ b/var/Widget/Do.php @@ -21,31 +21,31 @@ 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', - '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', - 'backup' => 'Widget_Backup' - ); + private $_map = [ + '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', + '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', + 'backup' => 'Widget_Backup' + ]; /** * 入口函数,初始化路由器 @@ -77,7 +77,7 @@ class Widget_Do extends Typecho_Widget } if (isset($widgetName) && class_exists($widgetName)) { - $reflectionWidget = new ReflectionClass($widgetName); + $reflectionWidget = new ReflectionClass($widgetName); if ($reflectionWidget->implementsInterface('Widget_Interface_Do')) { $this->widget($widgetName)->action(); return; diff --git a/var/Widget/Feedback.php b/var/Widget/Feedback.php index 5e199df0..c575d1a6 100644 --- a/var/Widget/Feedback.php +++ b/var/Widget/Feedback.php @@ -28,6 +28,124 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa */ private $_content; + /** + * 过滤评论内容 + * + * @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; + } elseif (!$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 + * @throws Typecho_Widget_Exception + */ + 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, ['comment', 'trackback'])) { + + /** 如果文章不允许反馈 */ + if ('comment' == $callback) { + /** 评论关闭 */ + if (!$this->_content->allow('comment')) { + throw new Typecho_Widget_Exception(_t('对不起,此内容的反馈被禁止.'), 403); + } + + /** 检查来源 */ + if ($this->options->commentsCheckReferer && 'false' != $this->parameter->checkReferer) { + $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 = ? AND ip = ?', $this->_content->cid, $this->request->getIp()) + ->order('created', Typecho_Db::SORT_DESC) + ->limit(1)); + + if ($latestComment && ($this->options->time - $latestComment['created'] > 0 && + $this->options->time - $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); + } + } + /** * 评论处理函数 * @@ -41,20 +159,20 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa $this->security->enable($this->options->commentsAntiSpam); $this->security->protect(); - $comment = array( - 'cid' => $this->_content->cid, - 'created' => $this->options->time, - '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' - ); + $comment = [ + 'cid' => $this->_content->cid, + 'created' => $this->options->time, + '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']) { + ->where('coid = ?', $parentId))) && $this->_content->cid == $parent['cid']) { $comment['parent'] = $parentId; } else { throw new Typecho_Widget_Exception(_t('父级评论不存在')); @@ -65,7 +183,7 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa $validator = new Typecho_Validate(); $validator->addRule('author', 'required', _t('必须填写用户名')); $validator->addRule('author', 'xssCheck', _t('请不要在用户名中使用特殊字符')); - $validator->addRule('author', array($this, 'requireUserLogin'), _t('您所使用的用户名已经被注册,请登录后再次提交')); + $validator->addRule('author', [$this, 'requireUserLogin'], _t('您所使用的用户名已经被注册,请登录后再次提交')); $validator->addRule('author', 'maxLength', _t('用户名最多包含150个字符'), 150); if ($this->options->commentsRequireMail && !$this->user->hasLogin()) { @@ -100,7 +218,7 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa } } - $expire = $this->options->time + $this->options->timezone + 30*24*3600; + $expire = $this->options->time + $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); @@ -112,7 +230,7 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa /** 记录登录用户的id */ $comment['authorId'] = $this->user->uid; } - + /** 评论者之前须有评论通过了审核 */ if (!$this->options->commentsRequireModeration && $this->options->commentsWhitelist) { if ($this->size($this->select()->where('author = ? AND mail = ? AND status = ?', $comment['author'], $comment['mail'], 'approved'))) { @@ -140,7 +258,7 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa $commentId = $this->insert($comment); Typecho_Cookie::delete('__typecho_remember_text'); $this->db->fetchRow($this->select()->where('coid = ?', $commentId) - ->limit(1), array($this, 'push')); + ->limit(1), [$this, 'push']); /** 评论完成接口 */ $this->pluginHandle()->finishComment($this); @@ -163,20 +281,20 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa /** 如果库中已经存在当前ip为spam的trackback则直接拒绝 */ if ($this->size($this->select() - ->where('status = ? AND ip = ?', 'spam', $this->request->getIp())) > 0) { + ->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->time, - 'agent' => $this->request->getAgent(), - 'ip' => $this->request->getIp(), - 'ownerId' => $this->_content->author->uid, - 'type' => 'trackback', - 'status' => $this->options->commentsRequireModeration ? 'waiting' : 'approved' - ); + $trackback = [ + 'cid' => $this->_content->cid, + 'created' => $this->options->time, + '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; @@ -185,16 +303,16 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa //检验格式 $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.', 255) - ->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.', 150); + ->addRule('url', 'url', 'Your url is not valid.') + ->addRule('url', 'maxLength', 'Your url is not valid.', 255) + ->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.', 150); $validator->setBreak(); if ($error = $validator->run($trackback)) { - $message = array('success' => 1, 'message' => current($error)); + $message = ['success' => 1, 'message' => current($error)]; $this->response->throwXml($message); } @@ -203,7 +321,7 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa /** 如果库中已经存在重复url则直接拒绝 */ if ($this->size($this->select() - ->where('cid = ? AND url = ? AND type <> ?', $this->_content->cid, $trackback['url'], 'comment')) > 0) { + ->where('cid = ? AND url = ? AND type <> ?', $this->_content->cid, $trackback['url'], 'comment')) > 0) { /** 使用403告诉机器人 */ throw new Typecho_Widget_Exception(_t('禁止重复提交'), 403); } @@ -218,124 +336,6 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa $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 - * @throws Typecho_Widget_Exception - */ - 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 && 'false' != $this->parameter->checkReferer) { - $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 = ? AND ip = ?', $this->_content->cid, $this->request->getIp()) - ->order('created', Typecho_Db::SORT_DESC) - ->limit(1)); - - if ($latestComment && ($this->options->time - $latestComment['created'] > 0 && - $this->options->time - $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); - } + $this->response->throwXml(['success' => 0, 'message' => 'Trackback has registered.']); } } diff --git a/var/Widget/Init.php b/var/Widget/Init.php index f8163c81..1de3e7f1 100644 --- a/var/Widget/Init.php +++ b/var/Widget/Init.php @@ -28,7 +28,7 @@ class Widget_Init extends Typecho_Widget /** 检查安装状态 */ if (!defined('__TYPECHO_INSTALL__') && !$options->installed) { - $options->update(array('value' => 1), Typecho_Db::get()->sql()->where('name = ?', 'installed')); + $options->update(['value' => 1], Typecho_Db::get()->sql()->where('name = ?', 'installed')); } /** 语言包初始化 */ diff --git a/var/Widget/Interface/Do.php b/var/Widget/Interface/Do.php index 355caf81..77910e53 100644 --- a/var/Widget/Interface/Do.php +++ b/var/Widget/Interface/Do.php @@ -1,4 +1,5 @@ <?php + /** * 可以被Widget_Do调用的接口 * diff --git a/var/Widget/Login.php b/var/Widget/Login.php index 97daf269..fc8ae3a7 100644 --- a/var/Widget/Login.php +++ b/var/Widget/Login.php @@ -53,7 +53,7 @@ class Widget_Login extends Widget_Abstract_Users implements Widget_Interface_Do /** 开始验证用户 **/ $valid = $this->user->login($this->request->name, $this->request->password, - false, 1 == $this->request->remember ? $this->options->time + $this->options->timezone + 30*24*3600 : 0); + false, 1 == $this->request->remember ? $this->options->time + $this->options->timezone + 30 * 24 * 3600 : 0); /** 比对密码 */ if (!$valid) { @@ -61,7 +61,7 @@ class Widget_Login extends Widget_Abstract_Users implements Widget_Interface_Do sleep(3); $this->pluginHandle()->loginFail($this->user, $this->request->name, - $this->request->password, 1 == $this->request->remember); + $this->request->password, 1 == $this->request->remember); Typecho_Cookie::set('__typecho_remember_name', $this->request->name); $this->widget('Widget_Notice')->set(_t('用户名或密码无效'), 'error'); @@ -69,7 +69,7 @@ class Widget_Login extends Widget_Abstract_Users implements Widget_Interface_Do } $this->pluginHandle()->loginSucceed($this->user, $this->request->name, - $this->request->password, 1 == $this->request->remember); + $this->request->password, 1 == $this->request->remember); /** 跳转验证后地址 */ if (!empty($this->request->referer)) { @@ -78,7 +78,7 @@ class Widget_Login extends Widget_Abstract_Users implements Widget_Interface_Do || 0 === strpos($this->request->referer, $this->options->siteUrl)) { $this->response->redirect($this->request->referer); } - } else if (!$this->user->pass('contributor', true)) { + } elseif (!$this->user->pass('contributor', true)) { /** 不允许普通用户直接跳转后台 */ $this->response->redirect($this->options->profileUrl); } diff --git a/var/Widget/Logout.php b/var/Widget/Logout.php index 05ba5bca..ce0f7a19 100644 --- a/var/Widget/Logout.php +++ b/var/Widget/Logout.php @@ -33,7 +33,7 @@ class Widget_Logout extends Widget_Abstract_Users implements Widget_Interface_Do $this->user->logout(); $this->pluginHandle()->logout(); - $this->response->goBack(NULL, $this->options->index); + $this->response->goBack(null, $this->options->index); @session_destroy(); } } diff --git a/var/Widget/Menu.php b/var/Widget/Menu.php index 0f36986e..fcffdc0e 100644 --- a/var/Widget/Menu.php +++ b/var/Widget/Menu.php @@ -15,13 +15,41 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Menu extends Typecho_Widget { + /** + * 当前菜单标题 + * @var string + */ + public $title; + + /** + * 当前增加项目链接 + * @var string + */ + public $addLink; + + /** + * 全局选项 + * + * @access protected + * @var Widget_Options + */ + protected $options; + + /** + * 用户对象 + * + * @access protected + * @var Widget_User + */ + protected $user; + /** * 父菜单列表 * * @access private * @var array */ - private $_menu = array(); + private $_menu = []; /** * 当前父菜单 @@ -47,34 +75,6 @@ class Widget_Menu extends Typecho_Widget */ private $_currentUrl; - /** - * 全局选项 - * - * @access protected - * @var Widget_Options - */ - protected $options; - - /** - * 用户对象 - * - * @access protected - * @var Widget_User - */ - protected $user; - - /** - * 当前菜单标题 - * @var string - */ - public $title; - - /** - * 当前增加项目链接 - * @var string - */ - public $addLink; - /** * 构造函数,初始化组件 * @@ -84,7 +84,7 @@ class Widget_Menu extends Typecho_Widget * @param mixed $params 参数列表 * @return void */ - public function __construct($request, $response, $params = NULL) + public function __construct($request, $response, $params = null) { parent::__construct($request, $response, $params); @@ -101,68 +101,69 @@ class Widget_Menu extends Typecho_Widget */ public function execute() { - $parentNodes = array(NULL, _t('控制台'), _t('撰写'), _t('管理'), _t('设置')); + $parentNodes = [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(_t('设置外观'), _t('设置外观'), 'options-theme.php', 'administrator', true), - array(_t('备份'), _t('备份'), 'backup.php', 'administrator'), - 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-categories.php', 'editor', false, 'category.php'), - array(_t('新增分类'), _t('新增分类'), 'category.php', 'editor', true), - array(array('Widget_Metas_Category_Admin', 'getMenuTitle'), array('Widget_Metas_Category_Admin', 'getMenuTitle'), 'manage-categories.php?parent=', 'editor', true, array('Widget_Metas_Category_Admin', 'getAddLink')), - array(array('Widget_Metas_Category_Edit', 'getMenuTitle'), array('Widget_Metas_Category_Edit', 'getMenuTitle'), 'category.php?mid=', 'editor', true), - array(array('Widget_Metas_Category_Edit', 'getMenuTitle'), array('Widget_Metas_Category_Edit', 'getMenuTitle'), 'category.php?parent=', 'editor', true), - array(_t('标签'), _t('管理标签'), 'manage-tags.php', 'editor'), - array(array('Widget_Metas_Tag_Admin', 'getMenuTitle'), array('Widget_Metas_Tag_Admin', 'getMenuTitle'), 'manage-tags.php?mid=', 'editor', true), - 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'), - )); + $childNodes = [ + [ + [_t('登录'), _t('登录到%s', $this->options->title), 'login.php', 'visitor'], + [_t('注册'), _t('注册到%s', $this->options->title), 'register.php', 'visitor'] + ], + [ + [_t('概要'), _t('网站概要'), 'index.php', 'subscriber'], + [_t('个人设置'), _t('个人设置'), 'profile.php', 'subscriber'], + [_t('插件'), _t('插件管理'), 'plugins.php', 'administrator'], + [['Widget_Plugins_Config', 'getMenuTitle'], ['Widget_Plugins_Config', 'getMenuTitle'], 'options-plugin.php?config=', 'administrator', true], + [_t('外观'), _t('网站外观'), 'themes.php', 'administrator'], + [['Widget_Themes_Files', 'getMenuTitle'], ['Widget_Themes_Files', 'getMenuTitle'], 'theme-editor.php', 'administrator', true], + [_t('设置外观'), _t('设置外观'), 'options-theme.php', 'administrator', true], + [_t('备份'), _t('备份'), 'backup.php', 'administrator'], + [_t('升级'), _t('升级程序'), 'upgrade.php', 'administrator', true], + [_t('欢迎'), _t('欢迎使用'), 'welcome.php', 'subscriber', true] + ], + [ + [_t('撰写文章'), _t('撰写新文章'), 'write-post.php', 'contributor'], + [['Widget_Contents_Post_Edit', 'getMenuTitle'], ['Widget_Contents_Post_Edit', 'getMenuTitle'], 'write-post.php?cid=', 'contributor', true], + [_t('创建页面'), _t('创建新页面'), 'write-page.php', 'editor'], + [['Widget_Contents_Page_Edit', 'getMenuTitle'], ['Widget_Contents_Page_Edit', 'getMenuTitle'], 'write-page.php?cid=', 'editor', true], + ], + [ + [_t('文章'), _t('管理文章'), 'manage-posts.php', 'contributor', false, 'write-post.php'], + [['Widget_Contents_Post_Admin', 'getMenuTitle'], ['Widget_Contents_Post_Admin', 'getMenuTitle'], 'manage-posts.php?uid=', 'contributor', true], + [_t('独立页面'), _t('管理独立页面'), 'manage-pages.php', 'editor', false, 'write-page.php'], + [_t('评论'), _t('管理评论'), 'manage-comments.php', 'contributor'], + [['Widget_Comments_Admin', 'getMenuTitle'], ['Widget_Comments_Admin', 'getMenuTitle'], 'manage-comments.php?cid=', 'contributor', true], + [_t('分类'), _t('管理分类'), 'manage-categories.php', 'editor', false, 'category.php'], + [_t('新增分类'), _t('新增分类'), 'category.php', 'editor', true], + [['Widget_Metas_Category_Admin', 'getMenuTitle'], ['Widget_Metas_Category_Admin', 'getMenuTitle'], 'manage-categories.php?parent=', 'editor', true, ['Widget_Metas_Category_Admin', 'getAddLink']], + [['Widget_Metas_Category_Edit', 'getMenuTitle'], ['Widget_Metas_Category_Edit', 'getMenuTitle'], 'category.php?mid=', 'editor', true], + [['Widget_Metas_Category_Edit', 'getMenuTitle'], ['Widget_Metas_Category_Edit', 'getMenuTitle'], 'category.php?parent=', 'editor', true], + [_t('标签'), _t('管理标签'), 'manage-tags.php', 'editor'], + [['Widget_Metas_Tag_Admin', 'getMenuTitle'], ['Widget_Metas_Tag_Admin', 'getMenuTitle'], 'manage-tags.php?mid=', 'editor', true], + [_t('文件'), _t('管理文件'), 'manage-medias.php', 'editor'], + [['Widget_Contents_Attachment_Edit', 'getMenuTitle'], ['Widget_Contents_Attachment_Edit', 'getMenuTitle'], 'media.php?cid=', 'contributor', true], + [_t('用户'), _t('管理用户'), 'manage-users.php', 'administrator', false, 'user.php'], + [_t('新增用户'), _t('新增用户'), 'user.php', 'administrator', true], + [['Widget_Users_Edit', 'getMenuTitle'], ['Widget_Users_Edit', 'getMenuTitle'], 'user.php?uid=', 'administrator', true], + ], + [ + [_t('基本'), _t('基本设置'), 'options-general.php', 'administrator'], + [_t('评论'), _t('评论设置'), 'options-discussion.php', 'administrator'], + [_t('阅读'), _t('阅读设置'), 'options-reading.php', 'administrator'], + [_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']; + $extendingParentMenu = empty($panelTable['parent']) ? [] : $panelTable['parent']; + $extendingChildMenu = empty($panelTable['child']) ? [] : $panelTable['child']; $currentUrl = $this->request->makeUriByRequest(); $adminUrl = $this->options->adminUrl; - $menu = array(); - $defaultChildeNode = array(NULL, NULL, NULL, 'administrator', false, NULL); + $menu = []; + $defaultChildeNode = [null, null, null, 'administrator', false, null]; $currentUrlParts = parse_url($currentUrl); - $currentUrlParams = array(); + $currentUrlParams = []; if (!empty($currentUrlParts['query'])) { parse_str($currentUrlParts['query'], $currentUrlParams); } @@ -176,22 +177,22 @@ class Widget_Menu extends Typecho_Widget } foreach ($extendingChildMenu as $key => $val) { - $childNodes[$key] = array_merge(isset($childNodes[$key]) ? $childNodes[$key] : array(), $val); + $childNodes[$key] = array_merge($childNodes[$key] ?? [], $val); } foreach ($parentNodes as $key => $parentNode) { // this is a simple struct than before - $children = array(); + $children = []; $showedChildrenCount = 0; - $firstUrl = NULL; - + $firstUrl = null; + foreach ($childNodes[$key] as $inKey => $childNode) { // magic merge $childNode += $defaultChildeNode; - list ($name, $title, $url, $access) = $childNode; + [$name, $title, $url, $access] = $childNode; $hidden = $childNode[4] ?? false; - $addLink = $childNode[5] ?? NULL; + $addLink = $childNode[5] ?? null; // 保存最原始的hidden信息 $orgHidden = $hidden; @@ -201,7 +202,7 @@ class Widget_Menu extends Typecho_Widget // compare url $urlParts = parse_url($url); - $urlParams = array(); + $urlParams = []; if (!empty($urlParts['query'])) { parse_str($urlParts['query'], $urlParams); } @@ -217,14 +218,14 @@ class Widget_Menu extends Typecho_Widget } } } - + if ($validate && basename($urlParts['path']) == 'extending.php' && !empty($currentUrlParams['panel']) && !empty($urlParams['panel']) - && $urlParams['panel'] != $currentUrlParams['panel']){ + && $urlParams['panel'] != $currentUrlParams['panel']) { $validate = false; } - + if ($hidden && $validate) { $hidden = false; } @@ -241,17 +242,17 @@ class Widget_Menu extends Typecho_Widget } if (is_array($name)) { - list($widget, $method) = $name; + [$widget, $method] = $name; $name = Typecho_Widget::widget($widget)->$method(); } - + if (is_array($title)) { - list($widget, $method) = $title; + [$widget, $method] = $title; $title = Typecho_Widget::widget($widget)->$method(); } if (is_array($addLink)) { - list($widget, $method) = $addLink; + [$widget, $method] = $addLink; $addLink = Typecho_Widget::widget($widget)->$method(); } } @@ -260,14 +261,14 @@ class Widget_Menu extends Typecho_Widget 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; + $this->addLink = $addLink ? Typecho_Common::url($addLink, $adminUrl) : null; } - $children[$inKey] = array( + $children[$inKey] = [ $name, $title, $url, @@ -275,10 +276,10 @@ class Widget_Menu extends Typecho_Widget $hidden, $addLink, $orgHidden - ); + ]; } - $menu[$key] = array($parentNode, $showedChildrenCount > 0, $firstUrl, $children); + $menu[$key] = [$parentNode, $showedChildrenCount > 0, $firstUrl, $children]; } $this->_menu = $menu; @@ -293,7 +294,7 @@ class Widget_Menu extends Typecho_Widget */ public function getCurrentMenu() { - return $this->_currentParent > 0 ? $this->_menu[$this->_currentParent][3][$this->_currentChild] : NULL; + return $this->_currentParent > 0 ? $this->_menu[$this->_currentParent][3][$this->_currentChild] : null; } /** @@ -309,7 +310,7 @@ class Widget_Menu extends Typecho_Widget continue; } - echo "<ul class=\"root" . ($key == $this->_currentParent ? ' ' . $class : NULL) + echo "<ul class=\"root" . ($key == $this->_currentParent ? ' ' . $class : null) . "\"><li class=\"parent\"><a href=\"{$node[2]}\">{$node[0]}</a>" . "</li><ul class=\"child\">"; @@ -319,16 +320,16 @@ class Widget_Menu extends Typecho_Widget $last = $inKey; } } - + foreach ($node[3] as $inKey => $inNode) { if ($inNode[4]) { continue; } - $classes = array(); + $classes = []; if ($key == $this->_currentParent && $inKey == $this->_currentChild) { $classes[] = $childClass; - } else if ($inNode[6]) { + } elseif ($inNode[6]) { continue; } @@ -336,7 +337,7 @@ class Widget_Menu extends Typecho_Widget $classes[] = 'last'; } - echo "<li" . (!empty($classes) ? ' class="' . implode(' ', $classes) . '"' : NULL) . + echo "<li" . (!empty($classes) ? ' class="' . implode(' ', $classes) . '"' : null) . "><a href=\"" . ($key == $this->_currentParent && $inKey == $this->_currentChild ? $this->_currentUrl : $inNode[2]) . "\">{$inNode[0]}</a></li>"; } diff --git a/var/Widget/Metas/Category/Admin.php b/var/Widget/Metas/Category/Admin.php index e5795b6e..367617db 100644 --- a/var/Widget/Metas/Category/Admin.php +++ b/var/Widget/Metas/Category/Admin.php @@ -2,16 +2,16 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; /** - * Widget_Metas_Category_Admin - * + * Widget_Metas_Category_Admin + * * @uses Widget_Metas_Category_List * @copyright Copyright (c) 2012 Typecho Team. (http://typecho.org) - * @author Joyqi <magike.net@gmail.com> + * @author Joyqi <magike.net@gmail.com> * @license GNU General Public License 2.0 */ class Widget_Metas_Category_Admin extends Widget_Metas_Category_List { - /** + /** * 执行函数 * * @access public @@ -27,8 +27,8 @@ class Widget_Metas_Category_Admin extends Widget_Metas_Category_List } /** - * 向上的返回链接 - * + * 向上的返回链接 + * * @access public * @return void */ @@ -47,7 +47,7 @@ class Widget_Metas_Category_Admin extends Widget_Metas_Category_List } else { echo '<a href="' . Typecho_Common::url('manage-categories.php', $this->options->adminUrl) . '">'; } - + echo '« '; _e('返回父级分类'); echo '</a>'; diff --git a/var/Widget/Metas/Category/Edit.php b/var/Widget/Metas/Category/Edit.php index cb096dc5..143fae67 100644 --- a/var/Widget/Metas/Category/Edit.php +++ b/var/Widget/Metas/Category/Edit.php @@ -42,9 +42,9 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget public function categoryExists($mid) { $category = $this->db->fetchRow($this->db->select() - ->from('table.metas') - ->where('type = ?', 'category') - ->where('mid = ?', $mid)->limit(1)); + ->from('table.metas') + ->where('type = ?', 'category') + ->where('mid = ?', $mid)->limit(1)); return $category ? true : false; } @@ -59,10 +59,10 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget public function nameExists($name) { $select = $this->db->select() - ->from('table.metas') - ->where('type = ?', 'category') - ->where('name = ?', $name) - ->limit(1); + ->from('table.metas') + ->where('type = ?', 'category') + ->where('name = ?', $name) + ->limit(1); if ($this->request->mid) { $select->where('mid <> ?', $this->request->mid); @@ -101,10 +101,10 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget public function slugExists($slug) { $select = $this->db->select() - ->from('table.metas') - ->where('type = ?', 'category') - ->where('slug = ?', Typecho_Common::slugName($slug)) - ->limit(1); + ->from('table.metas') + ->where('type = ?', 'category') + ->where('slug = ?', Typecho_Common::slugName($slug)) + ->limit(1); if ($this->request->mid) { $select->where('mid <> ?', $this->request->mid); @@ -114,6 +114,41 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget return $category ? false : true; } + /** + * 增加分类 + * + * @access public + * @return void + */ + public function insertCategory() + { + if ($this->form('insert')->validate()) { + $this->response->goBack(); + } + + /** 取出数据 */ + $category = $this->request->from('name', 'slug', 'description', 'parent'); + + $category['slug'] = Typecho_Common::slugName(empty($category['slug']) ? $category['name'] : $category['slug']); + $category['type'] = 'category'; + $category['order'] = $this->getMaxOrder('category', $category['parent']) + 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-categories.php' + . ($category['parent'] ? '?parent=' . $category['parent'] : ''), $this->options->adminUrl)); + } + /** * 生成表单 * @@ -121,24 +156,24 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget * @param string $action 表单动作 * @return Typecho_Widget_Helper_Form_Element */ - public function form($action = NULL) + public function form($action = null) { /** 构建表格 */ $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/metas-category-edit'), Typecho_Widget_Helper_Form::POST_METHOD); /** 分类名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, _t('分类名称') . ' *'); + $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('分类缩略名用于创建友好的链接形式, 建议使用字母, 数字, 下划线和横杠.')); + $slug = new Typecho_Widget_Helper_Form_Element_Text('slug', null, null, _t('分类缩略名'), + _t('分类缩略名用于创建友好的链接形式, 建议使用字母, 数字, 下划线和横杠.')); $form->addInput($slug); /** 父级分类 */ - $options = array(0 => _t('不选择')); - $parents = $this->widget('Widget_Metas_Category_List@options', + $options = [0 => _t('不选择')]; + $parents = $this->widget('Widget_Metas_Category_List@options', (isset($this->request->mid) ? 'ignore=' . $this->request->mid : '')); while ($parents->next()) { @@ -146,12 +181,12 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget } $parent = new Typecho_Widget_Helper_Form_Element_Select('parent', $options, $this->request->parent, _t('父级分类'), - _t('此分类将归档在您选择的父级分类下.')); + _t('此分类将归档在您选择的父级分类下.')); $form->addInput($parent); /** 分类描述 */ - $description = new Typecho_Widget_Helper_Form_Element_Textarea('description', NULL, NULL, - _t('分类描述'), _t('此文字用于描述分类, 在有的主题中它会被显示.')); + $description = new Typecho_Widget_Helper_Form_Element_Textarea('description', null, null, + _t('分类描述'), _t('此文字用于描述分类, 在有的主题中它会被显示.')); $form->addInput($description); /** 分类动作 */ @@ -170,8 +205,8 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget if (isset($this->request->mid) && 'insert' != $action) { /** 更新模式 */ $meta = $this->db->fetchRow($this->select() - ->where('mid = ?', $this->request->mid) - ->where('type = ?', 'category')->limit(1)); + ->where('mid = ?', $this->request->mid) + ->where('type = ?', 'category')->limit(1)); if (!$meta) { $this->response->redirect(Typecho_Common::url('manage-categories.php', $this->options->adminUrl)); @@ -198,56 +233,21 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget /** 给表单增加规则 */ if ('insert' == $action || 'update' == $action) { $name->addRule('required', _t('必须填写分类名称')); - $name->addRule(array($this, 'nameExists'), _t('分类名称已经存在')); - $name->addRule(array($this, 'nameToSlug'), _t('分类名称无法被转换为缩略名')); + $name->addRule([$this, 'nameExists'], _t('分类名称已经存在')); + $name->addRule([$this, 'nameToSlug'], _t('分类名称无法被转换为缩略名')); $name->addRule('xssCheck', _t('请不要在分类名称中使用特殊字符')); - $slug->addRule(array($this, 'slugExists'), _t('缩略名已经存在')); + $slug->addRule([$this, 'slugExists'], _t('缩略名已经存在')); $slug->addRule('xssCheck', _t('请不要在缩略名中使用特殊字符')); } if ('update' == $action) { $mid->addRule('required', _t('分类主键不存在')); - $mid->addRule(array($this, 'categoryExists'), _t('分类不存在')); + $mid->addRule([$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', 'parent'); - - $category['slug'] = Typecho_Common::slugName(empty($category['slug']) ? $category['name'] : $category['slug']); - $category['type'] = 'category'; - $category['order'] = $this->getMaxOrder('category', $category['parent']) + 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-categories.php' - . ($category['parent'] ? '?parent=' . $category['parent'] : ''), $this->options->adminUrl)); - } - /** * 更新分类 * @@ -272,10 +272,10 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget if ($parent['mid'] == $category['mid']) { $category['order'] = $parent['order']; - $this->update(array( - 'parent' => $current['parent'], - 'order' => $current['order'] - ), $this->db->sql()->where('mid = ?', $parent['mid'])); + $this->update([ + 'parent' => $current['parent'], + 'order' => $current['order'] + ], $this->db->sql()->where('mid = ?', $parent['mid'])); } else { $category['order'] = $this->getMaxOrder('category', $category['parent']) + 1; } @@ -290,7 +290,7 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget /** 提示信息 */ $this->widget('Widget_Notice')->set(_t('分类 <a href="%s">%s</a> 已经被更新', - $this->permalink, $this->name), 'success'); + $this->permalink, $this->name), 'success'); /** 转向原页 */ $this->response->redirect(Typecho_Common::url('manage-categories.php' @@ -313,14 +313,14 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget if ($this->delete($this->db->sql()->where('mid = ?', $category))) { $this->db->query($this->db->delete('table.relationships')->where('mid = ?', $category)); - $this->update(array('parent' => $parent), $this->db->sql()->where('parent = ?', $category)); + $this->update(['parent' => $parent], $this->db->sql()->where('parent = ?', $category)); $deleteCount ++; } } /** 提示信息 */ $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('分类已经删除') : _t('没有分类被删除'), - $deleteCount > 0 ? 'success' : 'notice'); + $deleteCount > 0 ? 'success' : 'notice'); /** 转向原页 */ $this->response->goBack(); @@ -337,7 +337,7 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget /** 验证数据 */ $validator = new Typecho_Validate(); $validator->addRule('merge', 'required', _t('分类主键不存在')); - $validator->addRule('merge', array($this, 'categoryExists'), _t('请选择需要合并的分类')); + $validator->addRule('merge', [$this, 'categoryExists'], _t('请选择需要合并的分类')); if ($error = $validator->run($this->request->from('merge'))) { $this->widget('Widget_Notice')->set($error, 'error'); @@ -377,7 +377,7 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget /** 转向原页 */ $this->response->redirect(Typecho_Common::url('manage-categories.php', $this->options->adminUrl)); } else { - $this->response->throwJson(array('success' => 1, 'message' => _t('分类排序已经完成'))); + $this->response->throwJson(['success' => 1, 'message' => _t('分类排序已经完成')]); } } @@ -415,25 +415,25 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget /** 验证数据 */ $validator = new Typecho_Validate(); $validator->addRule('mid', 'required', _t('分类主键不存在')); - $validator->addRule('mid', array($this, 'categoryExists'), _t('分类不存在')); + $validator->addRule('mid', [$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')); + ->rows(['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')); + ->where('type = ?', 'category')->limit(1), [$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->permalink, $this->name), 'success'); } /** 转向原页 */ @@ -455,15 +455,16 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget if (!empty($category)) { return _t('编辑分类 %s', $category['name']); } - - } if (isset($this->request->parent)) { + + } + if (isset($this->request->parent)) { $category = $this->db->fetchRow($this->select() ->where('type = ? AND mid = ?', 'category', $this->request->parent)); if (!empty($category)) { return _t('新增 %s 的子分类', $category['name']); } - + } else { return; } diff --git a/var/Widget/Metas/Category/List.php b/var/Widget/Metas/Category/List.php index e5abd18d..a4eed1f1 100644 --- a/var/Widget/Metas/Category/List.php +++ b/var/Widget/Metas/Category/List.php @@ -21,60 +21,60 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; class Widget_Metas_Category_List extends Widget_Abstract_Metas { /** - * 树状分类结构 - * + * 树状分类结构 + * * @var array * @access private */ - private $_treeViewCategories = array(); + private $_treeViewCategories = []; /** * _categoryOptions - * + * * @var mixed * @access private */ - private $_categoryOptions = NULL; + private $_categoryOptions = null; /** * 顶层分类 - * + * * @var array * @access private */ - private $_top = array(); + private $_top = []; /** - * 所有分类哈希表 - * + * 所有分类哈希表 + * * @var array * @access private */ - private $_map = array(); + private $_map = []; /** * 顺序流 - * + * * @var array * @access private */ - private $_orders = array(); + private $_orders = []; /** - * 所有子节点列表 - * + * 所有子节点列表 + * * @var array * @access private */ - private $_children = array(); + private $_children = []; /** - * 所有父节点列表 - * + * 所有父节点列表 + * * @var array * @access private */ - private $_parents = array(); + private $_parents = []; /** * 构造函数,初始化组件 @@ -84,7 +84,7 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas * @param mixed $response response对象 * @param mixed $params 参数列表 */ - public function __construct($request, $response, $params = NULL) + public function __construct($request, $response, $params = null) { parent::__construct($request, $response, $params); $this->parameter->setDefault('ignore=0¤t='); @@ -107,15 +107,103 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas $this->_top[] = $mid; } } - + // 预处理深度 $this->levelWalkCallback($this->_top); - $this->_map = array_map(array($this, 'filter'), $this->_map); + $this->_map = array_map([$this, 'filter'], $this->_map); + } + + /** + * 预处理分类迭代 + * + * @param array $categories + * @param array $parents + * @access private + */ + private function levelWalkCallback(array $categories, $parents = []) + { + foreach ($parents as $parent) { + if (!isset($this->_children[$parent])) { + $this->_children[$parent] = []; + } + + $this->_children[$parent] = array_merge($this->_children[$parent], $categories); + } + + foreach ($categories as $mid) { + $this->_orders[] = $mid; + $parent = $this->_map[$mid]['parent']; + + if (0 != $parent && isset($this->_map[$parent])) { + $levels = $this->_map[$parent]['levels'] + 1; + $this->_map[$mid]['levels'] = $levels; + } + + $this->_parents[$mid] = $parents; + + if (!empty($this->_treeViewCategories[$mid])) { + $new = $parents; + $new[] = $mid; + $this->levelWalkCallback($this->_treeViewCategories[$mid], $new); + } + } + } + + /** + * 执行函数 + * + * @access public + * @return void + */ + public function execute() + { + $this->stack = $this->getCategories($this->_orders); + } + + /** + * treeViewCategories + * + * @param $categoryOptions 输出选项 + * @access public + * @return void + */ + public function listCategories($categoryOptions = null) + { + //初始化一些变量 + $this->_categoryOptions = Typecho_Config::factory($categoryOptions); + $this->_categoryOptions->setDefault([ + 'wrapTag' => 'ul', + 'wrapClass' => '', + 'itemTag' => 'li', + 'itemClass' => '', + 'showCount' => false, + 'showFeed' => false, + 'countTemplate' => '(%d)', + 'feedTemplate' => '<a href="%s">RSS</a>' + ]); + + // 插件插件接口 + $this->pluginHandle()->trigger($plugged)->listCategories($this->_categoryOptions, $this); + + if (!$plugged) { + $this->stack = $this->getCategories($this->_top); + + if ($this->have()) { + echo '<' . $this->_categoryOptions->wrapTag . (empty($this->_categoryOptions->wrapClass) + ? '' : ' class="' . $this->_categoryOptions->wrapClass . '"') . '>'; + while ($this->next()) { + $this->treeViewCategoriesCallback(); + } + echo '</' . $this->_categoryOptions->wrapTag . '>'; + } + + $this->stack = $this->_map; + } } /** * 列出分类回调 - * + * * @access private */ private function treeViewCategoriesCallback() @@ -125,7 +213,7 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas return treeViewCategories($this, $categoryOptions); } - $classes = array(); + $classes = []; if ($categoryOptions->itemClass) { $classes[] = $categoryOptions->itemClass; @@ -135,7 +223,7 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas echo '<' . $categoryOptions->itemTag . ' class="' . implode(' ', $classes); - + if ($this->levels > 0) { echo ' category-child'; $this->levelsAlt(' category-level-odd', ' category-level-even'); @@ -145,7 +233,7 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas if ($this->mid == $this->parameter->current) { echo ' category-active'; - } else if (isset($this->_children[$this->mid]) && in_array($this->parameter->current, $this->_children[$this->mid])) { + } elseif (isset($this->_children[$this->mid]) && in_array($this->parameter->current, $this->_children[$this->mid])) { echo ' category-parent-active'; } @@ -167,67 +255,22 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas } /** - * 预处理分类迭代 - * - * @param array $categories - * @param array $parents - * @access private - */ - private function levelWalkCallback(array $categories, $parents = array()) - { - foreach ($parents as $parent) { - if (!isset($this->_children[$parent])) { - $this->_children[$parent] = array(); - } - - $this->_children[$parent] = array_merge($this->_children[$parent], $categories); - } - - foreach ($categories as $mid) { - $this->_orders[] = $mid; - $parent = $this->_map[$mid]['parent']; - - if (0 != $parent && isset($this->_map[$parent])) { - $levels = $this->_map[$parent]['levels'] + 1; - $this->_map[$mid]['levels'] = $levels; - } - - $this->_parents[$mid] = $parents; - - if (!empty($this->_treeViewCategories[$mid])) { - $new = $parents; - $new[] = $mid; - $this->levelWalkCallback($this->_treeViewCategories[$mid], $new); - } - } - } - - /** - * 子评论 - * - * @access protected - * @return array - */ - protected function ___children() - { - return isset($this->_treeViewCategories[$this->mid]) ? - $this->getCategories($this->_treeViewCategories[$this->mid]) : array(); - } - - /** - * 执行函数 + * 根据深度余数输出 * * @access public * @return void */ - public function execute() + public function levelsAlt() { - $this->stack = $this->getCategories($this->_orders); + $args = func_get_args(); + $num = func_num_args(); + $split = $this->levels % $num; + echo $args[(0 == $split ? $num : $split) - 1]; } /** - * treeViewCategories - * + * treeViewCategories + * * @access public * @return void */ @@ -241,7 +284,7 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas //在子评论之前输出 echo '<' . $this->_categoryOptions->wrapTag . (empty($this->_categoryOptions->wrapClass) - ? '' : ' class="' . $this->_categoryOptions->wrapClass . '"') . '>'; + ? '' : ' class="' . $this->_categoryOptions->wrapClass . '"') . '>'; foreach ($children as $child) { $this->row = $child; @@ -256,61 +299,6 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas } } - /** - * treeViewCategories - * - * @param $categoryOptions 输出选项 - * @access public - * @return void - */ - public function listCategories($categoryOptions = NULL) - { - //初始化一些变量 - $this->_categoryOptions = Typecho_Config::factory($categoryOptions); - $this->_categoryOptions->setDefault(array( - 'wrapTag' => 'ul', - 'wrapClass' => '', - 'itemTag' => 'li', - 'itemClass' => '', - 'showCount' => false, - 'showFeed' => false, - 'countTemplate' => '(%d)', - 'feedTemplate' => '<a href="%s">RSS</a>' - )); - - // 插件插件接口 - $this->pluginHandle()->trigger($plugged)->listCategories($this->_categoryOptions, $this); - - if (!$plugged) { - $this->stack = $this->getCategories($this->_top); - - if ($this->have()) { - echo '<' . $this->_categoryOptions->wrapTag . (empty($this->_categoryOptions->wrapClass) - ? '' : ' class="' . $this->_categoryOptions->wrapClass . '"') . '>'; - while ($this->next()) { - $this->treeViewCategoriesCallback(); - } - echo '</' . $this->_categoryOptions->wrapTag . '>'; - } - - $this->stack = $this->_map; - } - } - - /** - * 根据深度余数输出 - * - * @access public - * @return void - */ - public function levelsAlt() - { - $args = func_get_args(); - $num = func_num_args(); - $split = $this->levels % $num; - echo $args[(0 == $split ? $num : $split) -1]; - } - /** * 将每行的值压入堆栈 * @@ -332,29 +320,49 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas return $value; } + /** + * 获取某个分类所有父级节点缩略名 + * + * @param mixed $mid + * @access public + * @return array + */ + public function getAllParentsSlug($mid) + { + $parents = []; + + if (isset($this->_parents[$mid])) { + foreach ($this->_parents[$mid] as $parent) { + $parents[] = $this->_map[$parent]['slug']; + } + } + + return $parents; + } + /** * 获取某个分类下的所有子节点 - * - * @param mixed $mid + * + * @param mixed $mid * @access public * @return array */ public function getAllChildren($mid) { - return isset($this->_children[$mid]) ? $this->_children[$mid] : array(); + return isset($this->_children[$mid]) ? $this->_children[$mid] : []; } /** * 获取某个分类所有父级节点 - * - * @param mixed $mid + * + * @param mixed $mid * @access public * @return array */ public function getAllParents($mid) { - $parents = array(); - + $parents = []; + if (isset($this->_parents[$mid])) { foreach ($this->_parents[$mid] as $parent) { $parents[] = $this->_map[$parent]; @@ -364,10 +372,58 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas return $parents; } + /** + * 获取单个分类 + * + * @param integer $mid + * @access public + * @return mixed + */ + public function getCategory($mid) + { + return isset($this->_map[$mid]) ? $this->_map[$mid] : null; + } + + /** + * 子评论 + * + * @access protected + * @return array + */ + protected function ___children() + { + return isset($this->_treeViewCategories[$this->mid]) ? + $this->getCategories($this->_treeViewCategories[$this->mid]) : []; + } + + /** + * 获取多个分类 + * + * @param mixed $mids + * @access public + * @return array + */ + public function getCategories($mids) + { + $result = []; + + if (!empty($mids)) { + foreach ($mids as $mid) { + if (!$this->parameter->ignore + || ($this->parameter->ignore != $mid + && !$this->hasParent($mid, $this->parameter->ignore))) { + $result[] = $this->_map[$mid]; + } + } + } + + return $result; + } + /** * 是否拥有某个父级分类 * - * @param mixed $mid + * @param mixed $mid * @param mixed $parentId * @access public * @return bool @@ -384,61 +440,5 @@ class Widget_Metas_Category_List extends Widget_Abstract_Metas return false; } - - /** - * 获取某个分类所有父级节点缩略名 - * - * @param mixed $mid - * @access public - * @return array - */ - public function getAllParentsSlug($mid) - { - $parents = array(); - - if (isset($this->_parents[$mid])) { - foreach ($this->_parents[$mid] as $parent) { - $parents[] = $this->_map[$parent]['slug']; - } - } - - return $parents; - } - - /** - * 获取单个分类 - * - * @param integer $mid - * @access public - * @return mixed - */ - public function getCategory($mid) - { - return isset($this->_map[$mid]) ? $this->_map[$mid] : NULL; - } - - /** - * 获取多个分类 - * - * @param mixed $mids - * @access public - * @return array - */ - public function getCategories($mids) - { - $result = array(); - - if (!empty($mids)) { - foreach ($mids as $mid) { - if (!$this->parameter->ignore - || ($this->parameter->ignore != $mid - && !$this->hasParent($mid, $this->parameter->ignore))) { - $result[] = $this->_map[$mid]; - } - } - } - - return $result; - } } diff --git a/var/Widget/Metas/Tag/Admin.php b/var/Widget/Metas/Tag/Admin.php index 9c7fcb85..474b46fe 100644 --- a/var/Widget/Metas/Tag/Admin.php +++ b/var/Widget/Metas/Tag/Admin.php @@ -29,7 +29,7 @@ class Widget_Metas_Tag_Admin extends Widget_Metas_Tag_Cloud public function execute() { $select = $this->select()->where('type = ?', 'tag')->order('mid', Typecho_Db::SORT_DESC); - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } /** diff --git a/var/Widget/Metas/Tag/Cloud.php b/var/Widget/Metas/Tag/Cloud.php index 92de3503..46e993dc 100644 --- a/var/Widget/Metas/Tag/Cloud.php +++ b/var/Widget/Metas/Tag/Cloud.php @@ -28,9 +28,9 @@ class Widget_Metas_Tag_Cloud extends Widget_Abstract_Metas */ public function execute() { - $this->parameter->setDefault(array('sort' => 'count', 'ignoreZeroCount' => false, 'desc' => true, 'limit' => 0)); + $this->parameter->setDefault(['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); + $this->parameter->desc ? Typecho_Db::SORT_DESC : Typecho_Db::SORT_ASC); /** 忽略零数量 */ if ($this->parameter->ignoreZeroCount) { @@ -42,7 +42,7 @@ class Widget_Metas_Tag_Cloud extends Widget_Abstract_Metas $select->limit($this->parameter->limit); } - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } /** @@ -56,6 +56,6 @@ class Widget_Metas_Tag_Cloud extends Widget_Abstract_Metas { $args = func_get_args(); array_unshift($args, $this->count); - echo call_user_func_array(array('Typecho_Common', 'splitByCount'), $args); + echo call_user_func_array(['Typecho_Common', 'splitByCount'], $args); } } diff --git a/var/Widget/Metas/Tag/Edit.php b/var/Widget/Metas/Tag/Edit.php index 6bc64d78..715db9c9 100644 --- a/var/Widget/Metas/Tag/Edit.php +++ b/var/Widget/Metas/Tag/Edit.php @@ -43,9 +43,9 @@ class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Inte public function tagExists($mid) { $tag = $this->db->fetchRow($this->db->select() - ->from('table.metas') - ->where('type = ?', 'tag') - ->where('mid = ?', $mid)->limit(1)); + ->from('table.metas') + ->where('type = ?', 'tag') + ->where('mid = ?', $mid)->limit(1)); return $tag ? true : false; } @@ -60,10 +60,10 @@ class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Inte public function nameExists($name) { $select = $this->db->select() - ->from('table.metas') - ->where('type = ?', 'tag') - ->where('name = ?', $name) - ->limit(1); + ->from('table.metas') + ->where('type = ?', 'tag') + ->where('name = ?', $name) + ->limit(1); if ($this->request->mid) { $select->where('mid <> ?', $this->request->filter('int')->mid); @@ -102,10 +102,10 @@ class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Inte public function slugExists($slug) { $select = $this->db->select() - ->from('table.metas') - ->where('type = ?', 'tag') - ->where('slug = ?', Typecho_Common::slugName($slug)) - ->limit(1); + ->from('table.metas') + ->where('type = ?', 'tag') + ->where('slug = ?', Typecho_Common::slugName($slug)) + ->limit(1); if ($this->request->mid) { $select->where('mid <> ?', $this->request->mid); @@ -115,86 +115,6 @@ class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Inte 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($this->security->getIndex('/action/metas-tag-edit'), - 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', 'btn 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-tags.php', $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('标签名称无法被转换为缩略名')); - $name->addRule('xssCheck', _t('请不要标签名称中使用特殊字符')); - $slug->addRule(array($this, 'slugExists'), _t('缩略名已经存在')); - $slug->addRule('xssCheck', _t('请不要在缩略名中使用特殊字符')); - } - - if ('update' == $action) { - $mid->addRule('required', _t('标签主键不存在')); - $mid->addRule(array($this, 'tagExists'), _t('标签不存在')); - } - - return $form; - } - /** * 插入标签 * @@ -221,12 +141,92 @@ class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Inte /** 提示信息 */ $this->widget('Widget_Notice')->set(_t('标签 <a href="%s">%s</a> 已经被增加', - $this->permalink, $this->name), 'success'); + $this->permalink, $this->name), 'success'); /** 转向原页 */ $this->response->redirect(Typecho_Common::url('manage-tags.php', $this->options->adminUrl)); } + /** + * 生成表单 + * + * @access public + * @param string $action 表单动作 + * @return Typecho_Widget_Helper_Form + */ + public function form($action = null) + { + /** 构建表格 */ + $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/metas-tag-edit'), + 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', 'btn 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-tags.php', $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([$this, 'nameExists'], _t('标签名称已经存在')); + $name->addRule([$this, 'nameToSlug'], _t('标签名称无法被转换为缩略名')); + $name->addRule('xssCheck', _t('请不要标签名称中使用特殊字符')); + $slug->addRule([$this, 'slugExists'], _t('缩略名已经存在')); + $slug->addRule('xssCheck', _t('请不要在缩略名中使用特殊字符')); + } + + if ('update' == $action) { + $mid->addRule('required', _t('标签主键不存在')); + $mid->addRule([$this, 'tagExists'], _t('标签不存在')); + } + + return $form; + } + /** * 更新标签 * @@ -253,7 +253,7 @@ class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Inte /** 提示信息 */ $this->widget('Widget_Notice')->set(_t('标签 <a href="%s">%s</a> 已经被更新', - $this->permalink, $this->name), 'success'); + $this->permalink, $this->name), 'success'); /** 转向原页 */ $this->response->redirect(Typecho_Common::url('manage-tags.php', $this->options->adminUrl)); @@ -281,7 +281,7 @@ class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Inte /** 提示信息 */ $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('标签已经删除') : _t('没有标签被删除'), - $deleteCount > 0 ? 'success' : 'notice'); + $deleteCount > 0 ? 'success' : 'notice'); /** 转向原页 */ $this->response->redirect(Typecho_Common::url('manage-tags.php', $this->options->adminUrl)); @@ -333,7 +333,7 @@ class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Inte if ($tags) { foreach ($tags as $tag) { $this->refreshCountByTypeAndStatus($tag, 'post', 'publish'); - } + } // 自动清理标签 $this->clearTags(); diff --git a/var/Widget/Notice.php b/var/Widget/Notice.php index ac28bd08..1cbe1441 100644 --- a/var/Widget/Notice.php +++ b/var/Widget/Notice.php @@ -34,7 +34,7 @@ class Widget_Notice extends Typecho_Widget { $this->highlight = $theId; Typecho_Cookie::set('__typecho_notice_highlight', $theId, - $this->widget('Widget_Options')->time + $this->widget('Widget_Options')->timezone + 86400); + $this->widget('Widget_Options')->time + $this->widget('Widget_Options')->timezone + 86400); } /** @@ -58,14 +58,14 @@ class Widget_Notice extends Typecho_Widget */ public function set($value, $type = 'notice', $typeFix = 'notice') { - $notice = is_array($value) ? array_values($value) : array($value); + $notice = is_array($value) ? array_values($value) : [$value]; if (empty($type) && $typeFix) { $type = $typeFix; } Typecho_Cookie::set('__typecho_notice', Json::encode($notice), - $this->widget('Widget_Options')->time + $this->widget('Widget_Options')->timezone + 86400); + $this->widget('Widget_Options')->time + $this->widget('Widget_Options')->timezone + 86400); Typecho_Cookie::set('__typecho_notice_type', $type, - $this->widget('Widget_Options')->time + $this->widget('Widget_Options')->timezone + 86400); + $this->widget('Widget_Options')->time + $this->widget('Widget_Options')->timezone + 86400); } } diff --git a/var/Widget/Options.php b/var/Widget/Options.php index 6ed3309a..b1e38a55 100644 --- a/var/Widget/Options.php +++ b/var/Widget/Options.php @@ -20,22 +20,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Options extends Typecho_Widget { - /** - * 缓存的插件配置 - * - * @access private - * @var array - */ - private $_pluginConfig = array(); - - /** - * 缓存的个人插件配置 - * - * @access private - * @var array - */ - private $_personalPluginConfig = array(); - /** * 数据库对象 * @@ -43,6 +27,20 @@ class Widget_Options extends Typecho_Widget * @var Typecho_Db */ protected $db; + /** + * 缓存的插件配置 + * + * @access private + * @var array + */ + private $_pluginConfig = []; + /** + * 缓存的个人插件配置 + * + * @access private + * @var array + */ + private $_personalPluginConfig = []; /** * 构造函数,初始化组件 @@ -65,300 +63,6 @@ class Widget_Options extends Typecho_Widget } } - /** - * 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 || (defined('__TYPECHO_REWRITE__') && __TYPECHO_REWRITE__)) - ? $this->rootUrl : Typecho_Common::url('index.php', $this->rootUrl); - } - - /** - * 获取模板路径 - * - * @access protected - * @return string - */ - protected function ___themeUrl() - { - return defined('__TYPECHO_THEME_URL__') ? __TYPECHO_THEME_URL__ : - Typecho_Common::url(__TYPECHO_THEME_DIR__ . '/' . $this->theme, $this->siteUrl); - } - - /** - * 获取插件路径 - * - * @access protected - * @return string - */ - protected function ___pluginUrl() - { - return defined('__TYPECHO_PLUGIN_URL__') ? __TYPECHO_PLUGIN_URL__ : - 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->rootUrl); - } - - /** - * 获取登录地址 - * - * @access protected - * @return string - */ - protected function ___loginUrl() - { - return Typecho_Common::url('login.php', $this->adminUrl); - } - - /** - * 获取登录提交地址 - * - * @access protected - * @return string - */ - protected function ___loginAction() - { - return $this->widget('Widget_Security')->getTokenUrl( - Typecho_Router::url('do', array('action' => 'login', 'widget' => 'Login'), - Typecho_Common::url('index.php', $this->rootUrl))); - } - - /** - * 获取注册地址 - * - * @access protected - * @return string - */ - protected function ___registerUrl() - { - return Typecho_Common::url('register.php', $this->adminUrl); - } - - /** - * 获取登录提交地址 - * - * @access protected - * @return string - */ - protected function ___registerAction() - { - return $this->widget('Widget_Security')->getTokenUrl( - 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 $this->widget('Widget_Security')->getTokenUrl( - Typecho_Common::url('/action/logout', $this->index)); - } - - /** - * 获取系统时区 - * - * @access protected - * @return integer - */ - protected function ___serverTimezone() - { - return Typecho_Date::$serverTimezoneOffset; - } - - /** - * 获取GMT标准时间 - * - * @deprecated - * @access protected - * @return integer - */ - protected function ___gmtTime() - { - return Typecho_Date::gmtTime(); - } - - /** - * 获取时间 - * - * @deprecated - * @access protected - * @return integer - */ - protected function ___time() - { - return Typecho_Date::time(); - } - - /** - * 获取格式 - * - * @access protected - * @return string - */ - protected function ___contentType() - { - return isset($this->contentType) ? $this->contentType : 'text/html'; - } - - /** - * 软件名称 - * - * @access protected - * @return string - */ - protected function ___software() - { - [$software, $version] = explode(' ', $this->generator); - return $software; - } - - /** - * 软件版本 - * - * @access protected - * @return string - */ - protected function ___version() - { - [$software, $version] = explode(' ', $this->generator); - $pos = strpos($version, '/'); - - // fix for old version - if ($pos !== false) { - $version = substr($version, 0, $pos); - } - - 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,jpeg,png,tiff,bmp', 'mp3,mp4,mov,wmv,wma,rmvb,rm,avi,flv,ogg,oga,ogv', - 'txt,doc,docx,xls,xlsx,ppt,pptx,zip,rar,pdf'), $this->attachmentTypes); - - $attachmentTypesResult = array_unique(array_map('trim', preg_split("/(,|\.)/", $attachmentTypes))); - } - - return $attachmentTypesResult; - } - /** * 执行函数 * @@ -369,7 +73,7 @@ class Widget_Options extends Typecho_Widget { if (!empty($this->db)) { $values = $this->db->fetchAll($this->db->select()->from('table.options') - ->where('user = 0'), array($this, 'push')); + ->where('user = 0'), [$this, 'push']); // finish install if (empty($values)) { @@ -381,14 +85,14 @@ class Widget_Options extends Typecho_Widget /** 支持皮肤变量重载 */ 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; /** 动态获取根目录 */ @@ -402,7 +106,7 @@ class Widget_Options extends Typecho_Widget /** 初始化站点信息 */ if (defined('__TYPECHO_SITE_URL__')) { $this->siteUrl = __TYPECHO_SITE_URL__; - } else if (defined('__TYPECHO_DYNAMIC_SITE_URL__') && __TYPECHO_DYNAMIC_SITE_URL__) { + } elseif (defined('__TYPECHO_DYNAMIC_SITE_URL__') && __TYPECHO_DYNAMIC_SITE_URL__) { $this->siteUrl = $this->rootUrl; } @@ -424,12 +128,24 @@ class Widget_Options extends Typecho_Widget /** 解析路由并缓存 */ $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')); + $this->routingTable = array_merge([$parsedRoutingTable], $this->routingTable); + $this->db->query($this->db->update('table.options')->rows(['value' => serialize($this->routingTable)]) + ->where('name = ?', 'routingTable')); } } + /** + * 获取皮肤文件 + * + * @param string $theme + * @param string $file + * @return string + */ + public function themeFile($theme, $file = '') + { + return __TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . trim($theme, './') . '/' . trim($file, './'); + } + /** * 重载父类push函数,将所有变量值压入堆栈 * @@ -500,18 +216,6 @@ class Widget_Options extends Typecho_Widget echo Typecho_Common::url($path, $this->pluginUrl); } - /** - * 获取皮肤文件 - * - * @param string $theme - * @param string $file - * @return string - */ - public function themeFile($theme, $file = '') - { - return __TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . trim($theme, './') . '/' . trim($file, './'); - } - /** * 获取插件目录 * @@ -592,7 +296,7 @@ class Widget_Options extends Typecho_Widget { if (!isset($this->_pluginConfig[$pluginName])) { if (!empty($this->row['plugin:' . $pluginName]) - && false !== ($options = unserialize($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); @@ -613,7 +317,7 @@ class Widget_Options extends Typecho_Widget { if (!isset($this->_personalPluginConfig[$pluginName])) { if (!empty($this->row['_plugin:' . $pluginName]) - && false !== ($options = unserialize($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); @@ -622,4 +326,298 @@ class Widget_Options extends Typecho_Widget return $this->_personalPluginConfig[$pluginName]; } + + /** + * RSS2.0 + * + * @access protected + * @return string + */ + protected function ___feedUrl() + { + return Typecho_Router::url('feed', ['feed' => '/'], $this->index); + } + + /** + * RSS1.0 + * + * @access protected + * @return string + */ + protected function ___feedRssUrl() + { + return Typecho_Router::url('feed', ['feed' => '/rss/'], $this->index); + } + + /** + * ATOM1.O + * + * @access protected + * @return string + */ + protected function ___feedAtomUrl() + { + return Typecho_Router::url('feed', ['feed' => '/atom/'], $this->index); + } + + /** + * 评论RSS2.0聚合 + * + * @access protected + * @return string + */ + protected function ___commentsFeedUrl() + { + return Typecho_Router::url('feed', ['feed' => '/comments/'], $this->index); + } + + /** + * 评论RSS1.0聚合 + * + * @access protected + * @return string + */ + protected function ___commentsFeedRssUrl() + { + return Typecho_Router::url('feed', ['feed' => '/rss/comments/'], $this->index); + } + + /** + * 评论ATOM1.0聚合 + * + * @access protected + * @return string + */ + protected function ___commentsFeedAtomUrl() + { + return Typecho_Router::url('feed', ['feed' => '/atom/comments/'], $this->index); + } + + /** + * xmlrpc api地址 + * + * @access protected + * @return string + */ + protected function ___xmlRpcUrl() + { + return Typecho_Router::url('do', ['action' => 'xmlrpc'], $this->index); + } + + /** + * 获取解析路径前缀 + * + * @access protected + * @return string + */ + protected function ___index() + { + return ($this->rewrite || (defined('__TYPECHO_REWRITE__') && __TYPECHO_REWRITE__)) + ? $this->rootUrl : Typecho_Common::url('index.php', $this->rootUrl); + } + + /** + * 获取模板路径 + * + * @access protected + * @return string + */ + protected function ___themeUrl() + { + return defined('__TYPECHO_THEME_URL__') ? __TYPECHO_THEME_URL__ : + Typecho_Common::url(__TYPECHO_THEME_DIR__ . '/' . $this->theme, $this->siteUrl); + } + + /** + * 获取插件路径 + * + * @access protected + * @return string + */ + protected function ___pluginUrl() + { + return defined('__TYPECHO_PLUGIN_URL__') ? __TYPECHO_PLUGIN_URL__ : + 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->rootUrl); + } + + /** + * 获取登录地址 + * + * @access protected + * @return string + */ + protected function ___loginUrl() + { + return Typecho_Common::url('login.php', $this->adminUrl); + } + + /** + * 获取登录提交地址 + * + * @access protected + * @return string + */ + protected function ___loginAction() + { + return $this->widget('Widget_Security')->getTokenUrl( + Typecho_Router::url('do', ['action' => 'login', 'widget' => 'Login'], + Typecho_Common::url('index.php', $this->rootUrl))); + } + + /** + * 获取注册地址 + * + * @access protected + * @return string + */ + protected function ___registerUrl() + { + return Typecho_Common::url('register.php', $this->adminUrl); + } + + /** + * 获取登录提交地址 + * + * @access protected + * @return string + */ + protected function ___registerAction() + { + return $this->widget('Widget_Security')->getTokenUrl( + Typecho_Router::url('do', ['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 $this->widget('Widget_Security')->getTokenUrl( + Typecho_Common::url('/action/logout', $this->index)); + } + + /** + * 获取系统时区 + * + * @access protected + * @return integer + */ + protected function ___serverTimezone() + { + return Typecho_Date::$serverTimezoneOffset; + } + + /** + * 获取GMT标准时间 + * + * @return integer + * @deprecated + * @access protected + */ + protected function ___gmtTime() + { + return Typecho_Date::gmtTime(); + } + + /** + * 获取时间 + * + * @return integer + * @deprecated + * @access protected + */ + protected function ___time() + { + return Typecho_Date::time(); + } + + /** + * 获取格式 + * + * @access protected + * @return string + */ + protected function ___contentType() + { + return $this->contentType ?? 'text/html'; + } + + /** + * 软件名称 + * + * @access protected + * @return string + */ + protected function ___software() + { + [$software, $version] = explode(' ', $this->generator); + return $software; + } + + /** + * 软件版本 + * + * @access protected + * @return string + */ + protected function ___version() + { + [$software, $version] = explode(' ', $this->generator); + $pos = strpos($version, '/'); + + // fix for old version + if ($pos !== false) { + $version = substr($version, 0, $pos); + } + + return $version; + } + + /** + * 允许上传的文件类型 + * + * @access protected + * @return string + */ + protected function ___allowedAttachmentTypes() + { + $attachmentTypesResult = []; + + if (null != $this->attachmentTypes) { + $attachmentTypes = str_replace( + ['@image@', '@media@', '@doc@'], + ['gif,jpg,jpeg,png,tiff,bmp', 'mp3,mp4,mov,wmv,wma,rmvb,rm,avi,flv,ogg,oga,ogv', + 'txt,doc,docx,xls,xlsx,ppt,pptx,zip,rar,pdf'], $this->attachmentTypes); + + $attachmentTypesResult = array_unique(array_map('trim', preg_split("/(,|\.)/", $attachmentTypes))); + } + + return $attachmentTypesResult; + } } diff --git a/var/Widget/Options/Discussion.php b/var/Widget/Options/Discussion.php index 6f3afe63..07561714 100644 --- a/var/Widget/Options/Discussion.php +++ b/var/Widget/Options/Discussion.php @@ -21,6 +21,63 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widget_Interface_Do { + /** + * 执行更新动作 + * + * @access public + * @return void + */ + public function updateDiscussionSettings() + { + /** 验证格式 */ + if ($this->form()->validate()) { + $this->response->goBack(); + } + + $settings = $this->request->from('commentDateFormat', 'commentsListSize', 'commentsPageSize', 'commentsPageDisplay', 'commentsAvatar', + 'commentsOrder', 'commentsMaxNestingLevels', 'commentsUrlNofollow', 'commentsPostTimeout', 'commentsUniqueIpInterval', 'commentsWhitelist', 'commentsRequireMail', 'commentsAvatarRating', + 'commentsPostTimeout', 'commentsPostInterval', 'commentsRequireModeration', 'commentsRequireURL', 'commentsHTMLTagAllowed', 'commentsStopWords', 'commentsIpBlackList'); + $settings['commentsShow'] = $this->request->getArray('commentsShow'); + $settings['commentsPost'] = $this->request->getArray('commentsPost'); + + $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'] = min(7, 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'], ['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['commentsAntiSpam'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsAntiSpam'); + $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(['value' => $value], $this->db->sql()->where('name = ?', $name)); + } + + $this->widget('Widget_Notice')->set(_t("设置已经保存"), 'success'); + $this->response->goBack(); + } + /** * 输出表单结构 * @@ -31,49 +88,49 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge { /** 构建表格 */ $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/options-discussion'), - Typecho_Widget_Helper_Form::POST_METHOD); + Typecho_Widget_Helper_Form::POST_METHOD); /** 评论日期格式 */ - $commentDateFormat = new Typecho_Widget_Helper_Form_Element_Text('commentDateFormat', NULL, $this->options->commentDateFormat, - _t('评论日期格式'), _t('这是一个默认的格式,当你在模板中调用显示评论日期方法时, 如果没有指定日期格式, 将按照此格式输出.') . '<br />' + $commentDateFormat = new Typecho_Widget_Helper_Form_Element_Text('commentDateFormat', null, $this->options->commentDateFormat, + _t('评论日期格式'), _t('这是一个默认的格式,当你在模板中调用显示评论日期方法时, 如果没有指定日期格式, 将按照此格式输出.') . '<br />' . _t('具体写法请参考 <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 = 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"' : '') . '>' . _t('G - 普通') .'</option> - <option value="PG"' . ('PG' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>' . _t('PG - 13岁以上') .'</option> - <option value="R"' . ('R' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>' . _t('R - 17岁以上成人') .'</option> - <option value="X"' . ('X' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>' . _t('X - 限制级') .'</option></select> + $commentsShowOptions = [ + '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"' : '') . '>' . _t('G - 普通') . '</option> + <option value="PG"' . ('PG' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>' . _t('PG - 13岁以上') . '</option> + <option value="R"' . ('R' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>' . _t('R - 17岁以上成人') . '</option> + <option value="X"' . ('X' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>' . _t('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"> + '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-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"> + . _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(); + $commentsShowOptionsValue = []; if ($this->options->commentsShowCommentOnly) { $commentsShowOptionsValue[] = 'commentsShowCommentOnly'; } @@ -89,7 +146,7 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge if ($this->options->commentsUrlNofollow) { $commentsShowOptionsValue[] = 'commentsUrlNofollow'; } - + if ($this->options->commentsAvatar) { $commentsShowOptionsValue[] = 'commentsAvatar'; } @@ -103,26 +160,26 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge } $commentsShow = new Typecho_Widget_Helper_Form_Element_Checkbox('commentsShow', $commentsShowOptions, - $commentsShowOptionsValue, _t('评论显示')); + $commentsShowOptionsValue, _t('评论显示')); $form->addInput($commentsShow->multiMode()); /** 评论提交 */ - $commentsPostOptions = array( - 'commentsRequireModeration' => _t('所有评论必须经过审核'), - 'commentsWhitelist' => _t('评论者之前须有评论通过了审核'), - 'commentsRequireMail' => _t('必须填写邮箱'), - 'commentsRequireURL' => _t('必须填写网址'), - 'commentsCheckReferer' => _t('检查评论来源页 URL 是否与文章链接一致'), - 'commentsAntiSpam' => _t('开启反垃圾保护'), - 'commentsAutoClose' => _t('在文章发布 %s 天以后自动关闭评论', - '</label><input name="commentsPostTimeout" type="text" class="text num text-s" value="' . intval($this->options->commentsPostTimeout / (24 * 3600)) . '" id="commentsPost-commentsPostTimeout" /> + $commentsPostOptions = [ + 'commentsRequireModeration' => _t('所有评论必须经过审核'), + 'commentsWhitelist' => _t('评论者之前须有评论通过了审核'), + 'commentsRequireMail' => _t('必须填写邮箱'), + 'commentsRequireURL' => _t('必须填写网址'), + 'commentsCheckReferer' => _t('检查评论来源页 URL 是否与文章链接一致'), + 'commentsAntiSpam' => _t('开启反垃圾保护'), + '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" /> + '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(); + $commentsPostOptionsValue = []; if ($this->options->commentsRequireModeration) { $commentsPostOptionsValue[] = 'commentsRequireModeration'; } @@ -156,82 +213,25 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge } $commentsPost = new Typecho_Widget_Helper_Form_Element_Checkbox('commentsPost', $commentsPostOptions, - $commentsPostOptionsValue, _t('评论提交')); + $commentsPostOptionsValue, _t('评论提交')); $form->addInput($commentsPost->multiMode()); /** 允许使用的HTML标签和属性 */ - $commentsHTMLTagAllowed = new Typecho_Widget_Helper_Form_Element_Textarea('commentsHTMLTagAllowed', NULL, - $this->options->commentsHTMLTagAllowed, - _t('允许使用的HTML标签和属性'), _t('默认的用户评论不允许填写任何的HTML标签, 你可以在这里填写允许使用的HTML标签.') . '<br />' + $commentsHTMLTagAllowed = new Typecho_Widget_Helper_Form_Element_Textarea('commentsHTMLTagAllowed', null, + $this->options->commentsHTMLTagAllowed, + _t('允许使用的HTML标签和属性'), _t('默认的用户评论不允许填写任何的HTML标签, 你可以在这里填写允许使用的HTML标签.') . '<br />' . _t('比如: %s', '<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 = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置')); $submit->input->setAttribute('class', 'btn 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', 'commentsPageSize', 'commentsPageDisplay', 'commentsAvatar', - 'commentsOrder', 'commentsMaxNestingLevels', 'commentsUrlNofollow', 'commentsPostTimeout', 'commentsUniqueIpInterval', 'commentsWhitelist', 'commentsRequireMail', 'commentsAvatarRating', - 'commentsPostTimeout', 'commentsPostInterval', 'commentsRequireModeration', 'commentsRequireURL', 'commentsHTMLTagAllowed', 'commentsStopWords', 'commentsIpBlackList'); - $settings['commentsShow'] = $this->request->getArray('commentsShow'); - $settings['commentsPost'] = $this->request->getArray('commentsPost'); - - $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'] = min(7, 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['commentsAntiSpam'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsAntiSpam'); - $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(); - } - /** * 绑定动作 * diff --git a/var/Widget/Options/General.php b/var/Widget/Options/General.php index b25fa8bb..06678146 100644 --- a/var/Widget/Options/General.php +++ b/var/Widget/Options/General.php @@ -22,35 +22,9 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; class Widget_Options_General extends Widget_Abstract_Options implements Widget_Interface_Do { /** - * 获取语言列表 - * - * @access private - * @return array - */ - public static function getLangs() - { - $dir = defined('__TYPECHO_LANG_DIR__') ? __TYPECHO_LANG_DIR__ : __TYPECHO_ROOT_DIR__ . '/usr/langs'; - $files = glob($dir . '/*.mo'); - $langs = array('zh_CN' => '简体中文'); - - if (!empty($files)) { - foreach ($files as $file) { - $getText = new Typecho_I18n_GetText($file, false); - list ($name) = explode('.', basename($file)); - $title = $getText->translate('lang', $count); - $langs[$name] = $count > -1 ? $title : $name; - } - - ksort($langs); - } - - return $langs; - } - - /** - * 检查是否在语言列表中 - * - * @param mixed $lang + * 检查是否在语言列表中 + * + * @param mixed $lang * @access public * @return bool */ @@ -61,134 +35,29 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I } /** - * 输出表单结构 + * 获取语言列表 * - * @access public - * @return Typecho_Widget_Helper_Form + * @access private + * @return array */ - public function form() + public static function getLangs() { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/options-general'), - Typecho_Widget_Helper_Form::POST_METHOD); + $dir = defined('__TYPECHO_LANG_DIR__') ? __TYPECHO_LANG_DIR__ : __TYPECHO_ROOT_DIR__ . '/usr/langs'; + $files = glob($dir . '/*.mo'); + $langs = ['zh_CN' => '简体中文']; - /** 站点名称 */ - $title = new Typecho_Widget_Helper_Form_Element_Text('title', NULL, $this->options->title, _t('站点名称'), _t('站点的名称将显示在网页的标题处.')); - $title->input->setAttribute('class', 'w-100'); - $form->addInput($title->addRule('required', _t('请填写站点名称')) - ->addRule('xssCheck', _t('请不要在站点名称中使用特殊字符'))); + if (!empty($files)) { + foreach ($files as $file) { + $getText = new Typecho_I18n_GetText($file, false); + [$name] = explode('.', basename($file)); + $title = $getText->translate('lang', $count); + $langs[$name] = $count > - 1 ? $title : $name; + } - /** 站点地址 */ - if (!defined('__TYPECHO_SITE_URL__')) { - $siteUrl = new Typecho_Widget_Helper_Form_Element_Text('siteUrl', NULL, $this->options->originalSiteUrl, _t('站点地址'), _t('站点地址主要用于生成内容的永久链接.') . ($this->options->originalSiteUrl == $this->options->rootUrl ? - '' : '</p><p class="message notice mono">' . _t('当前地址 <strong>%s</strong> 与上述设定值不一致', - $this->options->rootUrl))); - $siteUrl->input->setAttribute('class', 'w-100 mono'); - $form->addInput($siteUrl->addRule('required', _t('请填写站点地址')) - ->addRule('url', _t('请填写一个合法的URL地址'))); + ksort($langs); } - /** 站点描述 */ - $description = new Typecho_Widget_Helper_Form_Element_Text('description', NULL, $this->options->description, _t('站点描述'), _t('站点描述将显示在网页代码的头部.')); - $form->addInput($description->addRule('xssCheck', _t('请不要在站点描述中使用特殊字符'))); - - /** 关键词 */ - $keywords = new Typecho_Widget_Helper_Form_Element_Text('keywords', NULL, $this->options->keywords, _t('关键词'), _t('请以半角逗号 "," 分割多个关键字.')); - $form->addInput($keywords->addRule('xssCheck', _t('请不要在关键词中使用特殊字符'))); - - /** 注册 */ - $allowRegister = new Typecho_Widget_Helper_Form_Element_Radio('allowRegister', array('0' => _t('不允许'), '1' => _t('允许')), $this->options->allowRegister, _t('是否允许注册'), - _t('允许访问者注册到你的网站, 默认的注册用户不享有任何写入权限.')); - $form->addInput($allowRegister); - - /** XMLRPC */ - $allowXmlRpc = new Typecho_Widget_Helper_Form_Element_Radio('allowXmlRpc', array('0' => _t('关闭'), '1' => _t('仅关闭 Pingback 接口'), '2' => _t('打开')), $this->options->allowXmlRpc, _t('XMLRPC 接口')); - $form->addInput($allowXmlRpc); - - /** 语言项 */ - // hack 语言扫描 - _t('lang'); - - $langs = self::getLangs(); - - if (count($langs) > 1) { - $lang = new Typecho_Widget_Helper_Form_Element_Select('lang', $langs, $this->options->lang, _t('语言')); - $form->addInput($lang->addRule(array($this, 'checkLang'), _t('所选择的语言包不存在'))); - } - - /** 时区 */ - $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 jpeg png tiff bmp)</code>', - '@media@' => _t('多媒体文件') . ' <code>(mp3 mp4 mov wmv wma rmvb rm avi flv ogg oga ogv)</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('用逗号 "," 将后缀名隔开, 例如: %s', '<code>cpp, h, mak</code>')); - $form->addInput($attachmentTypes->multiMode()); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('保存设置')); - $submit->input->setAttribute('class', 'btn primary'); - $form->addItem($submit); - - return $form; + return $langs; } /** @@ -215,45 +84,176 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I $this->response->goBack(); } - $settings = $this->request->from('title','description', 'keywords', 'allowRegister', 'allowXmlRpc', 'lang', 'timezone'); + $settings = $this->request->from('title', 'description', 'keywords', 'allowRegister', 'allowXmlRpc', 'lang', 'timezone'); $settings['attachmentTypes'] = $this->request->getArray('attachmentTypes'); if (!defined('__TYPECHO_SITE_URL__')) { $settings['siteUrl'] = rtrim($this->request->siteUrl, '/'); } - $attachmentTypes = array(); + $attachmentTypes = []; 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', 'strtolower')->attachmentTypesOther; if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@other@') && !empty($attachmentTypesOther)) { $types = implode(',', array_filter(array_map('trim', - explode(',', $attachmentTypesOther)), array($this, 'removeShell'))); + explode(',', $attachmentTypesOther)), [$this, 'removeShell'])); if (!empty($types)) { $attachmentTypes[] = $types; } } - + $settings['attachmentTypes'] = implode(',', $attachmentTypes); foreach ($settings as $name => $value) { - $this->update(array('value' => $value), $this->db->sql()->where('name = ?', $name)); + $this->update(['value' => $value], $this->db->sql()->where('name = ?', $name)); } $this->widget('Widget_Notice')->set(_t("设置已经保存"), 'success'); $this->response->goBack(); } + /** + * 输出表单结构 + * + * @access public + * @return Typecho_Widget_Helper_Form + */ + public function form() + { + /** 构建表格 */ + $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/options-general'), + Typecho_Widget_Helper_Form::POST_METHOD); + + /** 站点名称 */ + $title = new Typecho_Widget_Helper_Form_Element_Text('title', null, $this->options->title, _t('站点名称'), _t('站点的名称将显示在网页的标题处.')); + $title->input->setAttribute('class', 'w-100'); + $form->addInput($title->addRule('required', _t('请填写站点名称')) + ->addRule('xssCheck', _t('请不要在站点名称中使用特殊字符'))); + + /** 站点地址 */ + if (!defined('__TYPECHO_SITE_URL__')) { + $siteUrl = new Typecho_Widget_Helper_Form_Element_Text('siteUrl', null, $this->options->originalSiteUrl, _t('站点地址'), _t('站点地址主要用于生成内容的永久链接.') . ($this->options->originalSiteUrl == $this->options->rootUrl ? + '' : '</p><p class="message notice mono">' . _t('当前地址 <strong>%s</strong> 与上述设定值不一致', + $this->options->rootUrl))); + $siteUrl->input->setAttribute('class', 'w-100 mono'); + $form->addInput($siteUrl->addRule('required', _t('请填写站点地址')) + ->addRule('url', _t('请填写一个合法的URL地址'))); + } + + /** 站点描述 */ + $description = new Typecho_Widget_Helper_Form_Element_Text('description', null, $this->options->description, _t('站点描述'), _t('站点描述将显示在网页代码的头部.')); + $form->addInput($description->addRule('xssCheck', _t('请不要在站点描述中使用特殊字符'))); + + /** 关键词 */ + $keywords = new Typecho_Widget_Helper_Form_Element_Text('keywords', null, $this->options->keywords, _t('关键词'), _t('请以半角逗号 "," 分割多个关键字.')); + $form->addInput($keywords->addRule('xssCheck', _t('请不要在关键词中使用特殊字符'))); + + /** 注册 */ + $allowRegister = new Typecho_Widget_Helper_Form_Element_Radio('allowRegister', ['0' => _t('不允许'), '1' => _t('允许')], $this->options->allowRegister, _t('是否允许注册'), + _t('允许访问者注册到你的网站, 默认的注册用户不享有任何写入权限.')); + $form->addInput($allowRegister); + + /** XMLRPC */ + $allowXmlRpc = new Typecho_Widget_Helper_Form_Element_Radio('allowXmlRpc', ['0' => _t('关闭'), '1' => _t('仅关闭 Pingback 接口'), '2' => _t('打开')], $this->options->allowXmlRpc, _t('XMLRPC 接口')); + $form->addInput($allowXmlRpc); + + /** 语言项 */ + // hack 语言扫描 + _t('lang'); + + $langs = self::getLangs(); + + if (count($langs) > 1) { + $lang = new Typecho_Widget_Helper_Form_Element_Select('lang', $langs, $this->options->lang, _t('语言')); + $form->addInput($lang->addRule([$this, 'checkLang'], _t('所选择的语言包不存在'))); + } + + /** 时区 */ + $timezoneList = [ + "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)) : []; + $attachmentTypesOptionsValue = []; + + 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 = [ + '@image@' => _t('图片文件') . ' <code>(gif jpg jpeg png tiff bmp)</code>', + '@media@' => _t('多媒体文件') . ' <code>(mp3 mp4 mov wmv wma rmvb rm avi flv ogg oga ogv)</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('用逗号 "," 将后缀名隔开, 例如: %s', '<code>cpp, h, mak</code>')); + $form->addInput($attachmentTypes->multiMode()); + + /** 提交按钮 */ + $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置')); + $submit->input->setAttribute('class', 'btn primary'); + $form->addItem($submit); + + return $form; + } + /** * 绑定动作 * diff --git a/var/Widget/Options/Permalink.php b/var/Widget/Options/Permalink.php index 64359181..c7bb1bbc 100644 --- a/var/Widget/Options/Permalink.php +++ b/var/Widget/Options/Permalink.php @@ -21,70 +21,10 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ 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}', '{directory}', '{year}', '{month}', '{day}', '{mid}'), - array('[cid:digital]', '[slug]', '[category]', '[directory:split:0]', - '[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']; - - 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 + * + * @param mixed $value * @access public * @return void */ @@ -95,8 +35,8 @@ class Widget_Options_Permalink extends Widget_Abstract_Options implements Widget /** * 检查categoryPattern里是否含有必要参数 - * - * @param mixed $value + * + * @param mixed $value * @access public * @return void */ @@ -141,9 +81,9 @@ RewriteRule ^(.*)$ {$basePath}index.php/$1 [L] try { if ($client) { /** 发送一个rewrite地址请求 */ - $client->setData(array('do' => 'remoteCallback')) - ->setHeader('User-Agent', $this->options->generator) - ->send(Typecho_Common::url('/action/ajax', $this->options->siteUrl)); + $client->setData(['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; @@ -167,9 +107,9 @@ RewriteRule . {$basePath}index.php [L] if ($client) { /** 发送一个rewrite地址请求 */ - $client->setData(array('do' => 'remoteCallback')) - ->setHeader('User-Agent', $this->options->generator) - ->send(Typecho_Common::url('/action/ajax', $this->options->siteUrl)); + $client->setData(['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; @@ -186,98 +126,13 @@ RewriteRule . {$basePath}index.php [L] } return false; - } else if (file_exists(__TYPECHO_ROOT_DIR__ . '/.htaccess')) { + } elseif (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($this->security->getRootUrl('index.php/action/options-permalink'), - Typecho_Widget_Helper_Form::POST_METHOD); - - if (!defined('__TYPECHO_REWRITE__')) { - /** 是否使用地址重写功能 */ - $rewrite = new Typecho_Widget_Helper_Form_Element_Radio('rewrite', array('0' => _t('不启用'), '1' => _t('启用')), - $this->options->rewrite, _t('是否使用地址重写功能'), _t('地址重写即 rewrite 功能是某些服务器软件提供的优化内部连接的功能.') . '<br />' - . _t('打开此功能可以让你的链接看上去完全是静态地址.')); - - // disable rewrite check when rewrite opened - if (!$this->options->rewrite && !$this->request->is('enableRewriteAnyway=1')) { - $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文件, 这可能是产生这个错误的原因.') - . _t('请调整你的目录权限, 或者手动创建一个.htaccess文件.') . '</strong>'; - } - - $errorStr .= '<br /><input type="checkbox" name="enableRewriteAnyway" id="enableRewriteAnyway" value="1" />' - . ' <label for="enableRewriteAnyway">' . _t('如果你仍然想启用此功能, 请勾选这里') . '</label>'; - $rewrite->addRule(array($this, 'checkRewrite'), $errorStr); - } - - $form->addInput($rewrite); - } - - $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>/{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>{directory}</code> 多级分类, <code>{year}</code> 年, <code>{month}</code> 月, <code>{day}</code> 日') - . '<br />' . _t('选择一种合适的文章静态路径风格, 使得你的网站链接更加友好.') - . '<br />' . _t('一旦你选择了某种链接风格请不要轻易修改它.')); - 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 />' . _t('请在路径中至少包含上述的一项参数.')); - $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> 分类缩略名, <code>{directory}</code> 多级分类') - . '<br />' . _t('请在路径中至少包含上述的一项参数.')); - $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', 'btn primary'); - $form->addItem($submit); - - return $form; - } - /** * 执行更新动作 * @@ -299,7 +154,7 @@ RewriteRule . {$basePath}index.php [L] $this->request->postPattern = '/' . ltrim($this->encodeRule($this->request->customPattern), '/'); } - $settings = defined('__TYPECHO_REWRITE__') ? array() : $this->request->from('rewrite'); + $settings = defined('__TYPECHO_REWRITE__') ? [] : $this->request->from('rewrite'); if (isset($this->request->postPattern) && isset($this->request->pagePattern)) { $routingTable = $this->options->routingTable; $routingTable['post']['url'] = $this->request->postPattern; @@ -315,7 +170,7 @@ RewriteRule . {$basePath}index.php [L] } foreach ($settings as $name => $value) { - $this->update(array('value' => $value), $this->db->sql()->where('name = ?', $name)); + $this->update(['value' => $value], $this->db->sql()->where('name = ?', $name)); } if ($patternValid) { @@ -326,6 +181,155 @@ RewriteRule . {$basePath}index.php [L] $this->response->goBack(); } + /** + * 输出表单结构 + * + * @access public + * @return Typecho_Widget_Helper_Form + */ + public function form() + { + /** 构建表格 */ + $form = new Typecho_Widget_Helper_Form($this->security->getRootUrl('index.php/action/options-permalink'), + Typecho_Widget_Helper_Form::POST_METHOD); + + if (!defined('__TYPECHO_REWRITE__')) { + /** 是否使用地址重写功能 */ + $rewrite = new Typecho_Widget_Helper_Form_Element_Radio('rewrite', ['0' => _t('不启用'), '1' => _t('启用')], + $this->options->rewrite, _t('是否使用地址重写功能'), _t('地址重写即 rewrite 功能是某些服务器软件提供的优化内部连接的功能.') . '<br />' + . _t('打开此功能可以让你的链接看上去完全是静态地址.')); + + // disable rewrite check when rewrite opened + if (!$this->options->rewrite && !$this->request->is('enableRewriteAnyway=1')) { + $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文件, 这可能是产生这个错误的原因.') + . _t('请调整你的目录权限, 或者手动创建一个.htaccess文件.') . '</strong>'; + } + + $errorStr .= '<br /><input type="checkbox" name="enableRewriteAnyway" id="enableRewriteAnyway" value="1" />' + . ' <label for="enableRewriteAnyway">' . _t('如果你仍然想启用此功能, 请勾选这里') . '</label>'; + $rewrite->addRule([$this, 'checkRewrite'], $errorStr); + } + + $form->addInput($rewrite); + } + + $patterns = [ + '/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>/{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'); + } elseif (!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>{directory}</code> 多级分类, <code>{year}</code> 年, <code>{month}</code> 月, <code>{day}</code> 日') + . '<br />' . _t('选择一种合适的文章静态路径风格, 使得你的网站链接更加友好.') + . '<br />' . _t('一旦你选择了某种链接风格请不要轻易修改它.')); + 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 />' . _t('请在路径中至少包含上述的一项参数.')); + $pagePattern->input->setAttribute('class', 'mono w-60'); + $form->addInput($pagePattern->addRule([$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> 分类缩略名, <code>{directory}</code> 多级分类') + . '<br />' . _t('请在路径中至少包含上述的一项参数.')); + $categoryPattern->input->setAttribute('class', 'mono w-60'); + $form->addInput($categoryPattern->addRule([$this, 'checkCategoryPattern'], _t('分类路径中没有包含 {mid} 或者 {slug} '))); + + /** 提交按钮 */ + $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置')); + $submit->input->setAttribute('class', 'btn primary'); + $form->addItem($submit); + + return $form; + } + + /** + * 解析自定义的路径 + * + * @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 = ['custom' => ['url' => $this->encodeRule($this->request->customPattern)]]; + $parser = new Typecho_Router_Parser($currentTable); + $currentTable = $parser->parse(); + $regx = $currentTable['custom']['regx']; + + foreach ($routingTable as $key => $val) { + if ('post' != $key && 'page' != $key) { + $pathInfo = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $val['url']); + $pathInfo = str_replace(['{cid}', '{slug}', '{category}', '{year}', '{month}', '{day}', '{', '}'], + ['123', 'hello', 'default', '2008', '08', '08', '', ''], $pathInfo); + + if (preg_match($regx, $pathInfo)) { + return false; + } + } + } + + return true; + } + + /** + * 编码自定义的路径 + * + * @access private + * @param string $rule 待编码的路径 + * @return string + */ + protected function encodeRule($rule) + { + return str_replace(['{cid}', '{slug}', '{category}', '{directory}', '{year}', '{month}', '{day}', '{mid}'], + [ + '[cid:digital]', '[slug]', '[category]', '[directory:split:0]', + '[year:digital:4]', '[month:digital:2]', '[day:digital:2]', '[mid:digital]' + ], $rule); + } + /** * 绑定动作 * diff --git a/var/Widget/Options/Reading.php b/var/Widget/Options/Reading.php index d4a09ffd..ba30d435 100644 --- a/var/Widget/Options/Reading.php +++ b/var/Widget/Options/Reading.php @@ -21,130 +21,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Options_Reading extends Widget_Options_Permalink { - /** - * 输出表单结构 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function form() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/options-reading'), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 文章日期格式 */ - $postDateFormat = new Typecho_Widget_Helper_Form_Element_Text('postDateFormat', NULL, $this->options->postDateFormat, - _t('文章日期格式'), _t('此格式用于指定显示在文章归档中的日期默认显示格式.') . '<br />' - . _t('在某些主题中这个格式可能不会生效, 因为主题作者可以自定义日期格式.') . '<br />' - . _t('请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')); - $postDateFormat->input->setAttribute('class', 'w-40 mono'); - $form->addInput($postDateFormat->addRule('xssCheck', _t('请不要在日期格式中使用特殊字符'))); - - //首页显示 - $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->time)); - - 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($this->options->themeFile($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 />' - . _t('摘要的文字取决于你在文章中使用分隔符的位置.')); - $form->addInput($feedFullText); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('保存设置')); - $submit->input->setAttribute('class', 'btn primary'); - $form->addItem($submit); - - return $form; - } - /** * 执行更新动作 * @@ -161,16 +37,16 @@ class Widget_Options_Reading extends Widget_Options_Permalink $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->time) - ->where('cid = ?', $pageId = intval($this->request->frontPagePage)))) { + $this->db->fetchRow($this->db->select('cid') + ->from('table.contents')->where('type = ?', 'page') + ->where('status = ?', 'publish')->where('created < ?', $this->options->time) + ->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, " ./\\")))) { + } elseif ('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; @@ -196,13 +72,137 @@ class Widget_Options_Reading extends Widget_Options_Permalink } foreach ($settings as $name => $value) { - $this->update(array('value' => $value), $this->db->sql()->where('name = ?', $name)); + $this->update(['value' => $value], $this->db->sql()->where('name = ?', $name)); } $this->widget('Widget_Notice')->set(_t("设置已经保存"), 'success'); $this->response->goBack(); } + /** + * 输出表单结构 + * + * @access public + * @return Typecho_Widget_Helper_Form + */ + public function form() + { + /** 构建表格 */ + $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/options-reading'), + Typecho_Widget_Helper_Form::POST_METHOD); + + /** 文章日期格式 */ + $postDateFormat = new Typecho_Widget_Helper_Form_Element_Text('postDateFormat', null, $this->options->postDateFormat, + _t('文章日期格式'), _t('此格式用于指定显示在文章归档中的日期默认显示格式.') . '<br />' + . _t('在某些主题中这个格式可能不会生效, 因为主题作者可以自定义日期格式.') . '<br />' + . _t('请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')); + $postDateFormat->input->setAttribute('class', 'w-40 mono'); + $form->addInput($postDateFormat->addRule('xssCheck', _t('请不要在日期格式中使用特殊字符'))); + + //首页显示 + $frontPageParts = explode(':', $this->options->frontPage); + $frontPageType = $frontPageParts[0]; + $frontPageValue = count($frontPageParts) > 1 ? $frontPageParts[1] : ''; + + $frontPageOptions = [ + '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->time)); + + 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($this->options->themeFile($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', ['0' => _t('仅输出摘要'), '1' => _t('全文输出')], + $this->options->feedFullText, _t('聚合全文输出'), _t('如果你不希望在聚合中输出文章全文,请使用仅输出摘要选项.') . '<br />' + . _t('摘要的文字取决于你在文章中使用分隔符的位置.')); + $form->addInput($feedFullText); + + /** 提交按钮 */ + $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置')); + $submit->input->setAttribute('class', 'btn primary'); + $form->addItem($submit); + + return $form; + } + /** * 绑定动作 * diff --git a/var/Widget/Plugins/Config.php b/var/Widget/Plugins/Config.php index ffbe2d2e..cf8f86e1 100644 --- a/var/Widget/Plugins/Config.php +++ b/var/Widget/Plugins/Config.php @@ -19,6 +19,14 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Plugins_Config extends Widget_Abstract_Options { + /** + * 获取插件信息 + * + * @access public + * @var array + */ + public $info; + /** * 插件文件路径 * @@ -35,14 +43,6 @@ class Widget_Plugins_Config extends Widget_Abstract_Options */ private $_className; - /** - * 获取插件信息 - * - * @access public - * @var array - */ - public $info; - /** * 绑定动作 * @@ -57,7 +57,7 @@ class Widget_Plugins_Config extends Widget_Abstract_Options } /** 获取插件入口 */ - list($this->_pluginFileName, $this->_className) = Typecho_Plugin::portal($config, + [$this->_pluginFileName, $this->_className] = Typecho_Plugin::portal($config, $this->options->pluginDir($config)); $this->info = Typecho_Plugin::parseInfo($this->_pluginFileName); } @@ -98,7 +98,7 @@ class Widget_Plugins_Config extends Widget_Abstract_Options require_once $this->_pluginFileName; $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/plugins-edit?config=' . $pluginName), Typecho_Widget_Helper_Form::POST_METHOD); - call_user_func(array($this->_className, 'config'), $form); + call_user_func([$this->_className, 'config'], $form); $options = $this->options->plugin($pluginName); @@ -108,7 +108,7 @@ class Widget_Plugins_Config extends Widget_Abstract_Options } } - $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置')); + $submit = new Typecho_Widget_Helper_Form_Element_Submit(null, null, _t('保存设置')); $submit->input->setAttribute('class', 'btn primary'); $form->addItem($submit); return $form; diff --git a/var/Widget/Plugins/Edit.php b/var/Widget/Plugins/Edit.php index 1722f76d..2adf7137 100644 --- a/var/Widget/Plugins/Edit.php +++ b/var/Widget/Plugins/Edit.php @@ -26,49 +26,6 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte */ private $_configNoticed = false; - /** - * 手动配置插件变量 - * - * @param $pluginName 插件名称 - * @param array $settings 变量键值对 - * @param bool $isPersonal 是否为私人变量 - */ - 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'])); - } - } - } - } - /** * 启用插件 * @@ -78,7 +35,7 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte public function activate($pluginName) { /** 获取插件入口 */ - list($pluginFileName, $className) = Typecho_Plugin::portal($pluginName, $this->options->pluginDir($pluginName)); + [$pluginFileName, $className] = Typecho_Plugin::portal($pluginName, $this->options->pluginDir($pluginName)); $info = Typecho_Plugin::parseInfo($pluginFileName); /** 检测依赖信息 */ @@ -93,15 +50,15 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte /** 判断实例化是否成功 */ if (isset($activatedPlugins[$pluginName]) || !class_exists($className) - || !method_exists($className, 'activate')) { + || !method_exists($className, 'activate')) { throw new Typecho_Widget_Exception(_t('无法启用插件'), 500); } try { - $result = call_user_func(array($className, 'activate')); + $result = call_user_func([$className, 'activate']); Typecho_Plugin::activate($pluginName); - $this->update(array('value' => serialize(Typecho_Plugin::export())), - $this->db->sql()->where('name = ?', 'plugins')); + $this->update(['value' => serialize(Typecho_Plugin::export())], + $this->db->sql()->where('name = ?', 'plugins')); } catch (Typecho_Plugin_Exception $e) { /** 截获异常 */ $this->widget('Widget_Notice')->set($e->getMessage(), 'error'); @@ -109,10 +66,10 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte } $form = new Typecho_Widget_Helper_Form(); - call_user_func(array($className, 'config'), $form); + call_user_func([$className, 'config'], $form); $personalForm = new Typecho_Widget_Helper_Form(); - call_user_func(array($className, 'personalConfig'), $personalForm); + call_user_func([$className, 'personalConfig'], $personalForm); $options = $form->getValues(); $personalOptions = $personalForm->getValues(); @@ -142,6 +99,98 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte $this->response->goBack(); } + /** + * 用自有函数处理配置信息 + * + * @access public + * @param string $pluginName 插件名称 + * @param array $settings 配置值 + * @param boolean $isInit 是否为初始化 + * @return boolean + */ + public function configHandle($pluginName, array $settings, $isInit) + { + /** 获取插件入口 */ + [$pluginFileName, $className] = Typecho_Plugin::portal($pluginName, $this->options->pluginDir($pluginName)); + + if (!$isInit && method_exists($className, 'configCheck')) { + $result = call_user_func([$className, 'configCheck'], $settings); + + if (!empty($result) && is_string($result)) { + $this->widget('Widget_Notice')->set($result, 'notice'); + $this->_configNoticed = true; + } + } + + if (method_exists($className, 'configHandle')) { + call_user_func([$className, 'configHandle'], $settings, $isInit); + return true; + } + + return false; + } + + /** + * 手动配置插件变量 + * + * @param $pluginName 插件名称 + * @param array $settings 变量键值对 + * @param bool $isPersonal 是否为私人变量 + */ + 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([ + '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(['value' => serialize($value)]) + ->where('name = ?', $pluginName) + ->where('user = ?', $option['user'])); + } + } + } + } + + /** + * 用自有函数处理自定义配置信息 + * + * @access public + * @param string $className 类名 + * @param array $settings 配置值 + * @return boolean + */ + public function personalConfigHandle($className, array $settings) + { + if (method_exists($className, 'personalConfigHandle')) { + call_user_func([$className, 'personalConfigHandle'], $settings, true); + return true; + } + + return false; + } + /** * 禁用插件 * @@ -159,7 +208,7 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte try { /** 获取插件入口 */ - list($pluginFileName, $className) = Typecho_Plugin::portal($pluginName, $this->options->pluginDir($pluginName)); + [$pluginFileName, $className] = Typecho_Plugin::portal($pluginName, $this->options->pluginDir($pluginName)); } catch (Typecho_Plugin_Exception $e) { $pluginFileExist = false; @@ -180,12 +229,12 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte /** 判断实例化是否成功 */ if (!isset($activatedPlugins[$pluginName]) || !class_exists($className) - || !method_exists($className, 'deactivate')) { + || !method_exists($className, 'deactivate')) { throw new Typecho_Widget_Exception(_t('无法禁用插件'), 500); } try { - $result = call_user_func(array($className, 'deactivate')); + $result = call_user_func([$className, 'deactivate']); } catch (Typecho_Plugin_Exception $e) { /** 截获异常 */ $this->widget('Widget_Notice')->set($e->getMessage(), 'error'); @@ -197,8 +246,8 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte } Typecho_Plugin::deactivate($pluginName); - $this->update(array('value' => serialize(Typecho_Plugin::export())), - $this->db->sql()->where('name = ?', 'plugins')); + $this->update(['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)); @@ -245,55 +294,6 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte $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, $this->options->pluginDir($pluginName)); - - if (!$isInit && method_exists($className, 'configCheck')) { - $result = call_user_func(array($className, 'configCheck'), $settings); - - if (!empty($result) && is_string($result)) { - $this->widget('Widget_Notice')->set($result, 'notice'); - $this->_configNoticed = true; - } - } - - 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; - } - /** * 绑定动作 * diff --git a/var/Widget/Plugins/List.php b/var/Widget/Plugins/List.php index 22bffef4..a08567b8 100644 --- a/var/Widget/Plugins/List.php +++ b/var/Widget/Plugins/List.php @@ -25,7 +25,60 @@ class Widget_Plugins_List extends Typecho_Widget * @access public * @var array */ - public $activatedPlugins = array(); + public $activatedPlugins = []; + + /** + * 执行函数 + * + * @access public + * @return void + */ + public function execute() + { + /** 列出插件目录 */ + $pluginDirs = $this->getPlugins(); + $this->parameter->setDefault(['activated' => null]); + + /** 获取已启用插件 */ + $plugins = Typecho_Plugin::export(); + $this->activatedPlugins = $plugins['activated']; + + if (!empty($pluginDirs)) { + foreach ($pluginDirs as $key => $pluginDir) { + $parts = $this->getPlugin($pluginDir, $key); + if (empty($parts)) { + continue; + } + + [$pluginName, $pluginFileName] = $parts; + + if (file_exists($pluginFileName)) { + $info = Typecho_Plugin::parseInfo($pluginFileName); + $info['name'] = $pluginName; + + $info['dependence'] = Typecho_Plugin::checkDependence( + Typecho_Common::VERSION, + $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 ($info['activated'] == $this->parameter->activated) { + $this->push($info); + } + } + } + } + } /** * @return array @@ -48,71 +101,18 @@ class Widget_Plugins_List extends Typecho_Widget /** 获取插件主文件 */ $pluginFileName = $plugin . '/Plugin.php'; - } else if (file_exists($plugin) && 'index.php' != basename($plugin)) { + } elseif (file_exists($plugin) && 'index.php' != basename($plugin)) { $pluginFileName = $plugin; $part = explode('.', basename($plugin)); if (2 == count($part) && 'php' == $part[1]) { $pluginName = $part[0]; } else { - return NULL; + return null; } } else { - return NULL; + return null; } - return array($pluginName, $pluginFileName); - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 列出插件目录 */ - $pluginDirs = $this->getPlugins(); - $this->parameter->setDefault(array('activated' => NULL)); - - /** 获取已启用插件 */ - $plugins = Typecho_Plugin::export(); - $this->activatedPlugins = $plugins['activated']; - - if (!empty($pluginDirs)) { - foreach ($pluginDirs as $key => $pluginDir) { - $parts = $this->getPlugin($pluginDir, $key); - if (empty($parts)) { - continue; - } - - list ($pluginName, $pluginFileName) = $parts; - - if (file_exists($pluginFileName)) { - $info = Typecho_Plugin::parseInfo($pluginFileName); - $info['name'] = $pluginName; - - $info['dependence'] = Typecho_Plugin::checkDependence( - Typecho_Common::VERSION, - $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 ($info['activated'] == $this->parameter->activated) { - $this->push($info); - } - } - } - } + return [$pluginName, $pluginFileName]; } } diff --git a/var/Widget/Register.php b/var/Widget/Register.php index 5ffc2c9b..209d525d 100644 --- a/var/Widget/Register.php +++ b/var/Widget/Register.php @@ -1,5 +1,6 @@ <?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; + /** * 注册组件 * @@ -32,9 +33,9 @@ class Widget_Register extends Widget_Abstract_Users implements Widget_Interface_ $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('name', [$this, 'nameExists'], _t('用户名已经存在')); $validator->addRule('mail', 'required', _t('必须填写电子邮箱')); - $validator->addRule('mail', array($this, 'mailExists'), _t('电子邮箱地址已经存在')); + $validator->addRule('mail', [$this, 'mailExists'], _t('电子邮箱地址已经存在')); $validator->addRule('mail', 'email', _t('电子邮箱格式错误')); $validator->addRule('mail', 'maxLength', _t('电子邮箱最多包含64个字符'), 64); @@ -59,20 +60,20 @@ class Widget_Register extends Widget_Abstract_Users implements Widget_Interface_ $hasher = new PasswordHash(8, true); $generatedPassword = Typecho_Common::randString(7); - $dataStruct = array( - 'name' => $this->request->name, - 'mail' => $this->request->mail, - 'screenName'=> $this->request->name, - 'password' => $hasher->HashPassword($generatedPassword), - 'created' => $this->options->time, - 'group' => 'subscriber' - ); + $dataStruct = [ + 'name' => $this->request->name, + 'mail' => $this->request->mail, + 'screenName' => $this->request->name, + 'password' => $hasher->HashPassword($generatedPassword), + 'created' => $this->options->time, + 'group' => 'subscriber' + ]; $dataStruct = $this->pluginHandle()->register($dataStruct); $insertId = $this->insert($dataStruct); $this->db->fetchRow($this->select()->where('uid = ?', $insertId) - ->limit(1), array($this, 'push')); + ->limit(1), [$this, 'push']); $this->pluginHandle()->finishRegister($this); diff --git a/var/Widget/Security.php b/var/Widget/Security.php index 44c2569c..17780673 100644 --- a/var/Widget/Security.php +++ b/var/Widget/Security.php @@ -48,7 +48,7 @@ class Widget_Security extends Typecho_Widget */ public function systemCheck() { - $errors = array(); + $errors = []; // 检查安装文件的安全性 $installFile = __TYPECHO_ROOT_DIR__ . '/install.php'; @@ -80,39 +80,6 @@ class Widget_Security extends Typecho_Widget $this->_enabled = $enabled; } - /** - * 获取token - * - * @param string $suffix 后缀 - * @return string - */ - public function getToken($suffix) - { - return md5($this->_token . '&' . $suffix); - } - - /** - * 生成带token的路径 - * - * @param $path - * @param string|null $url - * @return string - */ - public function getTokenUrl($path, ?string $url = null) - { - $parts = parse_url($path); - $params = array(); - - if (!empty($parts['query'])) { - parse_str($parts['query'], $params); - } - - $params['_'] = $this->getToken($url ?: $this->request->getRequestUrl()); - $parts['query'] = http_build_query($params); - - return Typecho_Common::buildUrl($parts); - } - /** * 保护提交数据 * @@ -125,25 +92,14 @@ class Widget_Security extends Typecho_Widget } /** - * 获取安全的后台路径 + * 获取token * - * @param string $path + * @param string $suffix 后缀 * @return string */ - public function getAdminUrl($path) + public function getToken($suffix) { - return Typecho_Common::url($this->getTokenUrl($path), $this->_options->adminUrl); - } - - /** - * 获取安全的路由路径 - * - * @param $path - * @return string - */ - public function getIndex($path) - { - return Typecho_Common::url($this->getTokenUrl($path), $this->_options->index); + return md5($this->_token . '&' . $suffix); } /** @@ -157,6 +113,28 @@ class Widget_Security extends Typecho_Widget return Typecho_Common::url($this->getTokenUrl($path), $this->_options->rootUrl); } + /** + * 生成带token的路径 + * + * @param $path + * @param string|null $url + * @return string + */ + public function getTokenUrl($path, ?string $url = null) + { + $parts = parse_url($path); + $params = []; + + if (!empty($parts['query'])) { + parse_str($parts['query'], $params); + } + + $params['_'] = $this->getToken($url ?: $this->request->getRequestUrl()); + $parts['query'] = http_build_query($params); + + return Typecho_Common::buildUrl($parts); + } + /** * 输出后台安全路径 * @@ -167,6 +145,17 @@ class Widget_Security extends Typecho_Widget echo $this->getAdminUrl($path); } + /** + * 获取安全的后台路径 + * + * @param string $path + * @return string + */ + public function getAdminUrl($path) + { + return Typecho_Common::url($this->getTokenUrl($path), $this->_options->adminUrl); + } + /** * 输出安全的路由路径 * @@ -176,5 +165,16 @@ class Widget_Security extends Typecho_Widget { echo $this->getIndex($path); } + + /** + * 获取安全的路由路径 + * + * @param $path + * @return string + */ + public function getIndex($path) + { + return Typecho_Common::url($this->getTokenUrl($path), $this->_options->index); + } } diff --git a/var/Widget/Service.php b/var/Widget/Service.php index 73d7d810..214a1466 100644 --- a/var/Widget/Service.php +++ b/var/Widget/Service.php @@ -24,34 +24,7 @@ class Widget_Service extends Widget_Abstract_Options implements Widget_Interface * * @var array */ - public $asyncRequests = array(); - - /** - * 获取真实的 URL - * - * @return string - */ - private function getServiceUrl() - { - $url = Typecho_Common::url('/action/service', $this->options->index); - - if (defined('__TYPECHO_SERVICE_URL__')) { - $rootPath = rtrim(parse_url($this->options->rootUrl, PHP_URL_PATH), '/'); - $path = parse_url($url, PHP_URL_PATH); - $parts = parse_url(__TYPECHO_SERVICE_URL__); - - if (!empty($parts['path']) - && $parts['path'] != '/' - && rtrim($parts['path'], '/') != $rootPath) { - $path = Typecho_Common::url($path, $parts['path']); - } - - $parts['path'] = $path; - $url = Typecho_Common::buildUrl($parts); - } - - return $url; - } + public $asyncRequests = []; /** * 发送pingback实现 @@ -106,11 +79,11 @@ class Widget_Service extends Widget_Abstract_Options implements Widget_Interface if ($spider) { $spider->setTimeout(10) - ->send($url); + ->send($url); if (!($xmlrpcUrl = $spider->getResponseHeader('x-pingback'))) { if (preg_match("/<link[^>]*rel=[\"']pingback[\"'][^>]*href=[\"']([^\"']+)[\"'][^>]*>/i", - $spider->getResponseBody(), $out)) { + $spider->getResponseBody(), $out)) { $xmlrpcUrl = $out[1]; } } @@ -141,12 +114,12 @@ class Widget_Service extends Widget_Abstract_Options implements Widget_Interface if ($client) { try { $client->setTimeout(5) - ->setData(array( - 'blog_name' => $this->options->title . ' » ' . $post->title, - 'url' => $post->permalink, - 'excerpt' => $post->excerpt - )) - ->send($url); + ->setData([ + 'blog_name' => $this->options->title . ' » ' . $post->title, + 'url' => $post->permalink, + 'excerpt' => $post->excerpt + ]) + ->send($url); unset($client); } catch (Typecho_Http_Client_Exception $e) { @@ -169,18 +142,18 @@ class Widget_Service extends Widget_Abstract_Options implements Widget_Interface * @param array $trackback trackback的url * @return void */ - public function sendPing($cid, array $trackback = NULL) + public function sendPing($cid, array $trackback = null) { $this->user->pass('contributor'); if ($client = Typecho_Http_Client::get()) { try { - $input = array( + $input = [ 'do' => 'ping', 'cid' => $cid, 'token' => Typecho_Common::timeToken($this->options->secret) - ); + ]; if (!empty($trackback)) { $input['trackback'] = $trackback; @@ -198,13 +171,40 @@ class Widget_Service extends Widget_Abstract_Options implements Widget_Interface } } + /** + * 获取真实的 URL + * + * @return string + */ + private function getServiceUrl() + { + $url = Typecho_Common::url('/action/service', $this->options->index); + + if (defined('__TYPECHO_SERVICE_URL__')) { + $rootPath = rtrim(parse_url($this->options->rootUrl, PHP_URL_PATH), '/'); + $path = parse_url($url, PHP_URL_PATH); + $parts = parse_url(__TYPECHO_SERVICE_URL__); + + if (!empty($parts['path']) + && $parts['path'] != '/' + && rtrim($parts['path'], '/') != $rootPath) { + $path = Typecho_Common::url($path, $parts['path']); + } + + $parts['path'] = $path; + $url = Typecho_Common::buildUrl($parts); + } + + return $url; + } + /** * 请求异步服务 * * @param $method * @param mixed $params */ - public function requestService($method, $params = NULL) + public function requestService($method, $params = null) { static $called; @@ -216,11 +216,11 @@ class Widget_Service extends Widget_Abstract_Options implements Widget_Interface try { $client->setHeader('User-Agent', $this->options->generator) ->setTimeout(2) - ->setData(array( - 'do' => 'async', - 'requests' => Json::encode($self->asyncRequests), - 'token' => Typecho_Common::timeToken($this->options->secret) - )) + ->setData([ + 'do' => 'async', + 'requests' => Json::encode($self->asyncRequests), + 'token' => Typecho_Common::timeToken($this->options->secret) + ]) ->setMethod(Typecho_Http_Client::METHOD_POST) ->send($this->getServiceUrl()); @@ -233,7 +233,7 @@ class Widget_Service extends Widget_Abstract_Options implements Widget_Interface $called = true; } - $this->asyncRequests[] = array($method, $params); + $this->asyncRequests[] = [$method, $params]; } /** @@ -264,7 +264,7 @@ class Widget_Service extends Widget_Abstract_Options implements Widget_Interface if (!empty($requests)) { foreach ($requests as $request) { - list ($method, $params) = $request; + [$method, $params] = $request; $plugin->{$method}($params); } } diff --git a/var/Widget/Stat.php b/var/Widget/Stat.php index f7cc773b..b5082281 100644 --- a/var/Widget/Stat.php +++ b/var/Widget/Stat.php @@ -45,7 +45,7 @@ class Widget_Stat extends Typecho_Widget * @param mixed $params 参数列表 * @return void */ - public function __construct($request, $response, $params = NULL) + public function __construct($request, $response, $params = null) { parent::__construct($request, $response, $params); @@ -64,10 +64,10 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ?', 'post') + ->where('table.contents.status = ?', 'publish'))->num; } /** @@ -78,10 +78,10 @@ class Widget_Stat extends Typecho_Widget */ protected function ___waitingPostsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ? OR table.contents.type = ?', 'post', 'post_draft') - ->where('table.contents.status = ?', 'waiting'))->num; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ? OR table.contents.type = ?', 'post', 'post_draft') + ->where('table.contents.status = ?', 'waiting'))->num; } /** @@ -92,9 +92,9 @@ class Widget_Stat extends Typecho_Widget */ protected function ___draftPostsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post_draft'))->num; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ?', 'post_draft'))->num; } /** @@ -105,11 +105,11 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ?', 'post') + ->where('table.contents.status = ?', 'publish') + ->where('table.contents.authorId = ?', $this->user->uid))->num; } /** @@ -120,11 +120,11 @@ class Widget_Stat extends Typecho_Widget */ protected function ___myWaitingPostsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ? OR table.contents.type = ?', 'post', 'post_draft') - ->where('table.contents.status = ?', 'waiting') - ->where('table.contents.authorId = ?', $this->user->uid))->num; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ? OR table.contents.type = ?', 'post', 'post_draft') + ->where('table.contents.status = ?', 'waiting') + ->where('table.contents.authorId = ?', $this->user->uid))->num; } /** @@ -135,10 +135,10 @@ class Widget_Stat extends Typecho_Widget */ protected function ___myDraftPostsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post_draft') - ->where('table.contents.authorId = ?', $this->user->uid))->num; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ?', 'post_draft') + ->where('table.contents.authorId = ?', $this->user->uid))->num; } /** @@ -149,11 +149,11 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['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; } /** @@ -164,11 +164,11 @@ class Widget_Stat extends Typecho_Widget */ protected function ___currentWaitingPostsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ? OR table.contents.type = ?', 'post', 'post_draft') - ->where('table.contents.status = ?', 'waiting') - ->where('table.contents.authorId = ?', $this->request->filter('int')->uid))->num; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ? OR table.contents.type = ?', 'post', 'post_draft') + ->where('table.contents.status = ?', 'waiting') + ->where('table.contents.authorId = ?', $this->request->filter('int')->uid))->num; } /** @@ -179,10 +179,10 @@ class Widget_Stat extends Typecho_Widget */ protected function ___currentDraftPostsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post_draft') - ->where('table.contents.authorId = ?', $this->request->filter('int')->uid))->num; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ?', 'post_draft') + ->where('table.contents.authorId = ?', $this->request->filter('int')->uid))->num; } /** @@ -193,10 +193,10 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ?', 'page') + ->where('table.contents.status = ?', 'publish'))->num; } /** @@ -207,9 +207,9 @@ class Widget_Stat extends Typecho_Widget */ protected function ___draftPagesNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'page_draft'))->num; + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ?', 'page_draft'))->num; } /** @@ -220,9 +220,9 @@ class Widget_Stat extends Typecho_Widget */ protected function ___publishedCommentsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'approved'))->num; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.status = ?', 'approved'))->num; } /** @@ -233,9 +233,9 @@ class Widget_Stat extends Typecho_Widget */ protected function ___waitingCommentsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'waiting'))->num; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.status = ?', 'waiting'))->num; } /** @@ -246,9 +246,9 @@ class Widget_Stat extends Typecho_Widget */ protected function ___spamCommentsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'spam'))->num; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.status = ?', 'spam'))->num; } /** @@ -259,10 +259,10 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.status = ?', 'approved') + ->where('table.comments.ownerId = ?', $this->user->uid))->num; } /** @@ -273,10 +273,10 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.status = ?', 'waiting') + ->where('table.comments.ownerId = ?', $this->user->uid))->num; } /** @@ -287,12 +287,12 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.status = ?', 'spam') + ->where('table.comments.ownerId = ?', $this->user->uid))->num; } - + /** * 获取当前文章的评论数目 * @@ -301,9 +301,9 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.cid = ?', $this->request->filter('int')->cid))->num; } /** @@ -314,10 +314,10 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.status = ?', 'approved') + ->where('table.comments.cid = ?', $this->request->filter('int')->cid))->num; } /** @@ -328,10 +328,10 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.status = ?', 'waiting') + ->where('table.comments.cid = ?', $this->request->filter('int')->cid))->num; } /** @@ -342,10 +342,10 @@ class Widget_Stat extends Typecho_Widget */ 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; + return $this->db->fetchObject($this->db->select(['COUNT(coid)' => 'num']) + ->from('table.comments') + ->where('table.comments.status = ?', 'spam') + ->where('table.comments.cid = ?', $this->request->filter('int')->cid))->num; } /** @@ -356,12 +356,12 @@ class Widget_Stat extends Typecho_Widget */ protected function ___categoriesNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(mid)' => 'num')) - ->from('table.metas') - ->where('table.metas.type = ?', 'category'))->num; + return $this->db->fetchObject($this->db->select(['COUNT(mid)' => 'num']) + ->from('table.metas') + ->where('table.metas.type = ?', 'category'))->num; } - - /** + + /** * 获取标签数目 * * @access protected @@ -369,8 +369,8 @@ class Widget_Stat extends Typecho_Widget */ protected function ___tagsNum() { - return $this->db->fetchObject($this->db->select(array('COUNT(mid)' => 'num')) - ->from('table.metas') - ->where('table.metas.type = ?', 'tag'))->num; + return $this->db->fetchObject($this->db->select(['COUNT(mid)' => 'num']) + ->from('table.metas') + ->where('table.metas.type = ?', 'tag'))->num; } } diff --git a/var/Widget/Themes/Config.php b/var/Widget/Themes/Config.php index 00f9761c..fbfce3d8 100644 --- a/var/Widget/Themes/Config.php +++ b/var/Widget/Themes/Config.php @@ -29,7 +29,7 @@ class Widget_Themes_Config extends Widget_Abstract_Options public function execute() { $this->user->pass('administrator'); - + if (!self::isExists()) { throw new Typecho_Widget_Exception(_t('外观配置功能不存在'), 404); } @@ -37,7 +37,7 @@ class Widget_Themes_Config extends Widget_Abstract_Options /** * 配置功能是否存在 - * + * * @access public * @return boolean */ @@ -48,12 +48,12 @@ class Widget_Themes_Config extends Widget_Abstract_Options if (file_exists($configFile)) { require_once $configFile; - + if (function_exists('themeConfig')) { return true; } } - + return false; } @@ -69,14 +69,14 @@ class Widget_Themes_Config extends Widget_Abstract_Options 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 = new Typecho_Widget_Helper_Form_Element_Submit(null, null, _t('保存设置')); $submit->input->setAttribute('class', 'btn primary'); $form->addItem($submit); return $form; diff --git a/var/Widget/Themes/Edit.php b/var/Widget/Themes/Edit.php index abd6a13d..ef0087cb 100644 --- a/var/Widget/Themes/Edit.php +++ b/var/Widget/Themes/Edit.php @@ -36,29 +36,29 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter /** 删除原外观设置信息 */ $this->delete($this->db->sql()->where('name = ?', 'theme:' . $this->options->theme)); - $this->update(array('value' => $theme), $this->db->sql()->where('name = ?', 'theme')); + $this->update(['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')); + $this->update(['value' => 'recent'], $this->db->sql()->where('name = ?', 'frontPage')); } - + $configFile = $this->options->themeFile($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->insert([ + 'name' => 'theme:' . $theme, + 'value' => serialize($options), + 'user' => 0 + ]); } } } @@ -71,6 +71,24 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter } } + /** + * 用自有函数处理配置信息 + * + * @access public + * @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; + } + /** * 编辑外观文件 * @@ -98,7 +116,7 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter throw new Typecho_Widget_Exception(_t('您编辑的文件不存在')); } } - + /** * 配置外观 * @@ -120,14 +138,14 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter if (!$this->configHandle($settings, false)) { if ($this->options->__get('theme:' . $theme)) { - $this->update(array('value' => serialize($settings)), - $this->db->sql()->where('name = ?', 'theme:' . $theme)); + $this->update(['value' => serialize($settings)], + $this->db->sql()->where('name = ?', 'theme:' . $theme)); } else { - $this->insert(array( - 'name' => 'theme:' . $theme, - 'value' => serialize($settings), - 'user' => 0 - )); + $this->insert([ + 'name' => 'theme:' . $theme, + 'value' => serialize($settings), + 'user' => 0 + ]); } } @@ -141,24 +159,6 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter $this->response->redirect(Typecho_Common::url('options-theme.php', $this->options->adminUrl)); } - /** - * 用自有函数处理配置信息 - * - * @access public - * @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; - } - /** * 绑定动作 * diff --git a/var/Widget/Themes/Files.php b/var/Widget/Themes/Files.php index 1782b72f..d898b065 100644 --- a/var/Widget/Themes/Files.php +++ b/var/Widget/Themes/Files.php @@ -61,15 +61,15 @@ class Widget_Themes_Files extends Typecho_Widget $this->_currentFile = $this->request->get('file', 'index.php'); if (preg_match("/^([_0-9a-z-\.\ ])+$/i", $this->_currentFile) - && file_exists($dir . '/' . $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) - )); + $this->push([ + 'file' => $file, + 'theme' => $this->_currentTheme, + 'current' => ($file == $this->_currentFile) + ]); } } @@ -112,8 +112,8 @@ class Widget_Themes_Files extends Typecho_Widget public function currentIsWriteable() { return is_writeable($this->widget('Widget_Options') - ->themeFile($this->_currentTheme, $this->_currentFile)) - && (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__); + ->themeFile($this->_currentTheme, $this->_currentFile)) + && (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__); } /** diff --git a/var/Widget/Themes/List.php b/var/Widget/Themes/List.php index 9cac7791..42665cb2 100644 --- a/var/Widget/Themes/List.php +++ b/var/Widget/Themes/List.php @@ -21,26 +21,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Widget_Themes_List extends Typecho_Widget { - /** - * @return array - */ - protected function getThemes() - { - return glob(__TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/*', GLOB_ONLYDIR); - } - - /** - * get theme - * - * @param string $theme - * @param mixed $index - * @return string - */ - protected function getTheme($theme, $index) - { - return basename($theme); - } - /** * 执行函数 * @@ -53,8 +33,8 @@ class Widget_Themes_List extends Typecho_Widget if ($themes) { $options = $this->widget('Widget_Options'); - $activated = 0; - $result = array(); + $activated = 0; + $result = []; foreach ($themes as $key => $theme) { $themeFile = $theme . '/index.php'; @@ -83,7 +63,27 @@ class Widget_Themes_List extends Typecho_Widget $clone = $result[$activated]; unset($result[$activated]); array_unshift($result, $clone); - array_filter($result, array($this, 'push')); + array_filter($result, [$this, 'push']); } } + + /** + * @return array + */ + protected function getThemes() + { + return glob(__TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/*', GLOB_ONLYDIR); + } + + /** + * get theme + * + * @param string $theme + * @param mixed $index + * @return string + */ + protected function getTheme($theme, $index) + { + return basename($theme); + } } diff --git a/var/Widget/Upgrade.php b/var/Widget/Upgrade.php index 1cd29a43..baa87059 100644 --- a/var/Widget/Upgrade.php +++ b/var/Widget/Upgrade.php @@ -45,7 +45,7 @@ class Widget_Upgrade extends Widget_Abstract_Options implements Widget_Interface [$ver, $rev] = explode('r', $b); $b = str_replace('_', '.', $rev); - return version_compare($a, $b, '>') ? 1 : -1; + return version_compare($a, $b, '>') ? 1 : - 1; } /** diff --git a/var/Widget/Upload.php b/var/Widget/Upload.php index 970d9945..b28849f7 100644 --- a/var/Widget/Upload.php +++ b/var/Widget/Upload.php @@ -22,6 +22,238 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface //上传文件目录 const UPLOAD_DIR = '/usr/uploads'; + /** + * 删除文件 + * + * @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, + defined('__TYPECHO_UPLOAD_URL__') ? __TYPECHO_UPLOAD_URL__ : $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, + defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__)); + } + + /** + * 初始化函数 + * + * @access public + * @return void + */ + public function action() + { + if ($this->user->pass('contributor', true) && $this->request->isPost()) { + $this->security->protect(); + if ($this->request->is('do=modify&cid')) { + $this->modify(); + } else { + $this->upload(); + } + } else { + $this->response->setStatus(403); + } + } + + /** + * 执行升级程序 + * + * @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'), [$this, 'push']); + + if (!$this->have()) { + $this->response->setStatus(404); + exit; + } + + if (!$this->allow('edit')) { + $this->response->setStatus(403); + exit; + } + + // xhr的send无法支持utf8 + if ($this->request->isAjax()) { + $file['name'] = urldecode($file['name']); + } + + $result = self::modifyHandle($this->row, $file); + + if (false !== $result) { + $this->pluginHandle()->beforeModify($result); + + $this->update([ + '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'), [$this, 'push']); + + /** 增加插件接口 */ + $this->pluginHandle()->modify($this); + + $this->response->throwJson([$this->attachment->url, [ + '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 + ]]); + } + } + } + + $this->response->throwJson(false); + } + + /** + * 修改文件处理函数,如果需要实现自己的文件哈希或者特殊的文件系统,请在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; + } + + $ext = self::getSafeName($file['name']); + + if ($content['attachment']->type != $ext) { + return false; + } + + $path = Typecho_Common::url($content['attachment']->path, + defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __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; + } + } elseif (isset($file['bytes'])) { + + @unlink($path); + + //直接写入文件 + if (!file_put_contents($path, $file['bytes'])) { + return false; + } + } elseif (isset($file['bits'])) { + + @unlink($path); + + //直接写入文件 + if (!file_put_contents($path, $file['bits'])) { + return false; + } + } else { + return false; + } + + if (!isset($file['size'])) { + $file['size'] = filesize($path); + } + + //返回相对存储路径 + return [ + 'name' => $content['attachment']->name, + 'path' => $content['attachment']->path, + 'size' => $file['size'], + 'type' => $content['attachment']->type, + 'mime' => $content['attachment']->mime + ]; + } + + /** + * 获取安全的文件名 + * + * @param string $name + * @static + * @access private + * @return string + */ + private static function getSafeName(&$name) + { + $name = str_replace(['"', '<', '>'], '', $name); + $name = str_replace('\\', '/', $name); + $name = false === strpos($name, '/') ? ('a' . $name) : str_replace('/', '/a', $name); + $info = pathinfo($name); + $name = substr($info['basename'], 1); + + return isset($info['extension']) ? strtolower($info['extension']) : ''; + } + /** * 创建上传路径 * @@ -55,247 +287,6 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface return self::makeUploadDir($path); } - /** - * 获取安全的文件名 - * - * @param string $name - * @static - * @access private - * @return string - */ - private static function getSafeName(&$name) - { - $name = str_replace(array('"', '<', '>'), '', $name); - $name = str_replace('\\', '/', $name); - $name = false === strpos($name, '/') ? ('a' . $name) : str_replace('/', '/a', $name); - $info = pathinfo($name); - $name = substr($info['basename'], 1); - - return isset($info['extension']) ? strtolower($info['extension']) : ''; - } - - /** - * 上传文件处理函数,如果需要实现自己的文件哈希或者特殊的文件系统,请在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; - } - - $ext = self::getSafeName($file['name']); - - if (!self::checkFileType($ext)) { - return false; - } - - $date = new Typecho_Date(); - $path = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR, - defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __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 if (isset($file['bits'])) { - - //直接写入文件 - if (!file_put_contents($path, $file['bits'])) { - return false; - } - } else { - return false; - } - - if (!isset($file['size'])) { - $file['size'] = filesize($path); - } - - //返回相对存储路径 - return array( - 'name' => $file['name'], - 'path' => (defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR) - . '/' . $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; - } - - $ext = self::getSafeName($file['name']); - - if ($content['attachment']->type != $ext) { - return false; - } - - $path = Typecho_Common::url($content['attachment']->path, - defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __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 if (isset($file['bits'])) { - - @unlink($path); - - //直接写入文件 - if (!file_put_contents($path, $file['bits'])) { - 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, - defined('__TYPECHO_UPLOAD_URL__') ? __TYPECHO_UPLOAD_URL__ : $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, - defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __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); - } - /** * 执行升级程序 * @@ -316,16 +307,16 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface 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 - ); + $struct = [ + '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; @@ -338,21 +329,21 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface $insertId = $this->insert($struct); $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $insertId) - ->where('table.contents.type = ?', 'attachment'), array($this, 'push')); + ->where('table.contents.type = ?', 'attachment'), [$this, 'push']); /** 增加插件接口 */ $this->pluginHandle()->upload($this); - $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 - ))); + $this->response->throwJson([$this->attachment->url, [ + '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 + ]]); } } @@ -362,83 +353,92 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface } /** - * 执行升级程序 + * 上传文件处理函数,如果需要实现自己的文件哈希或者特殊的文件系统,请在options表里把uploadHandle改成自己的函数 * * @access public - * @return void + * @param array $file 上传的文件 + * @return mixed */ - public function modify() + public static function uploadHandle($file) { - 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 (empty($file['name'])) { + return false; + } - if (!$this->have()) { - $this->response->setStatus(404); - exit; - } + $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasUploaded)->uploadHandle($file); + if ($hasUploaded) { + return $result; + } - if (!$this->allow('edit')) { - $this->response->setStatus(403); - exit; - } + $ext = self::getSafeName($file['name']); - // xhr的send无法支持utf8 - if ($this->request->isAjax()) { - $file['name'] = urldecode($file['name']); - } + if (!self::checkFileType($ext)) { + return false; + } - $result = self::modifyHandle($this->row, $file); + $date = new Typecho_Date(); + $path = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR, + defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__) + . '/' . $date->year . '/' . $date->month; - 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); - - $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 - ))); - } + //创建上传目录 + if (!is_dir($path)) { + if (!self::makeUploadDir($path)) { + return false; } } - $this->response->throwJson(false); - } + //获取文件名 + $fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext; + $path = $path . '/' . $fileName; - /** - * 初始化函数 - * - * @access public - * @return void - */ - public function action() - { - if ($this->user->pass('contributor', true) && $this->request->isPost()) { - $this->security->protect(); - if ($this->request->is('do=modify&cid')) { - $this->modify(); - } else { - $this->upload(); + if (isset($file['tmp_name'])) { + + //移动上传文件 + if (!@move_uploaded_file($file['tmp_name'], $path)) { + return false; + } + } elseif (isset($file['bytes'])) { + + //直接写入文件 + if (!file_put_contents($path, $file['bytes'])) { + return false; + } + } elseif (isset($file['bits'])) { + + //直接写入文件 + if (!file_put_contents($path, $file['bits'])) { + return false; } } else { - $this->response->setStatus(403); + return false; } + + if (!isset($file['size'])) { + $file['size'] = filesize($path); + } + + //返回相对存储路径 + return [ + 'name' => $file['name'], + 'path' => (defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR) + . '/' . $date->year . '/' . $date->month . '/' . $fileName, + 'size' => $file['size'], + 'type' => $ext, + 'mime' => Typecho_Common::mimeContentType($path) + ]; + } + + /** + * 检查文件名 + * + * @access private + * @param string $ext 扩展名 + * @return boolean + */ + public static function checkFileType($ext) + { + $options = Typecho_Widget::widget('Widget_Options'); + return in_array($ext, $options->allowedAttachmentTypes); } } diff --git a/var/Widget/User.php b/var/Widget/User.php index b856e263..4aadca7c 100644 --- a/var/Widget/User.php +++ b/var/Widget/User.php @@ -12,20 +12,18 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; class Widget_User extends Typecho_Widget { /** - * 用户 + * 用户组 * - * @access private + * @access public * @var array */ - private $_user; - - /** - * 是否已经登录 - * - * @access private - * @var boolean - */ - private $_hasLogin = NULL; + public $groups = [ + 'administrator' => 0, + 'editor' => 1, + 'contributor' => 2, + 'subscriber' => 3, + 'visitor' => 4 + ]; /** * 全局选项 @@ -44,18 +42,20 @@ class Widget_User extends Typecho_Widget protected $db; /** - * 用户组 + * 用户 * - * @access public + * @access private * @var array */ - public $groups = array( - 'administrator' => 0, - 'editor' => 1, - 'contributor' => 2, - 'subscriber' => 3, - 'visitor' => 4 - ); + private $_user; + + /** + * 是否已经登录 + * + * @access private + * @var boolean + */ + private $_hasLogin = null; /** * 构造函数,初始化组件 @@ -65,7 +65,7 @@ class Widget_User extends Typecho_Widget * @param mixed $response response对象 * @param mixed $params 参数列表 */ - public function __construct($request, $response, $params = NULL) + public function __construct($request, $response, $params = null) { parent::__construct($request, $response, $params); @@ -84,7 +84,7 @@ class Widget_User extends Typecho_Widget { if ($this->hasLogin()) { $rows = $this->db->fetchAll($this->db->select() - ->from('table.options')->where('user = ?', $this->_user['uid'])); + ->from('table.options')->where('user = ?', $this->_user['uid'])); $this->push($this->_user); @@ -94,12 +94,60 @@ class Widget_User extends Typecho_Widget //更新最后活动时间 $this->db->query($this->db - ->update('table.users') - ->rows(array('activated' => $this->options->time)) - ->where('uid = ?', $this->_user['uid'])); + ->update('table.users') + ->rows(['activated' => $this->options->time]) + ->where('uid = ?', $this->_user['uid'])); } } + /** + * 判断用户是否已经登录 + * + * @access public + * @return boolean + */ + 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 + * @return void + */ + public function logout() + { + $this->pluginHandle()->trigger($logoutPluggable)->logout(); + if ($logoutPluggable) { + return; + } + + Typecho_Cookie::delete('__typecho_uid'); + Typecho_Cookie::delete('__typecho_authCode'); + } + /** * 以用户名和密码登录 * @@ -120,9 +168,9 @@ class Widget_User extends Typecho_Widget /** 开始验证用户 **/ $user = $this->db->fetchRow($this->db->select() - ->from('table.users') - ->where((strpos($name, '@') ? 'mail' : 'name') . ' = ?', $name) - ->limit(1)); + ->from('table.users') + ->where((strpos($name, '@') ? 'mail' : 'name') . ' = ?', $name) + ->limit(1)); if (empty($user)) { return false; @@ -156,43 +204,6 @@ class Widget_User extends Typecho_Widget $this->pluginHandle()->loginFail($this, $name, $password, $temporarily, $expire); return false; } - - /** - * 只需要提供uid或者完整user数组即可登录的方法, 多用于插件等特殊场合 - * - * @access public - * @param int | array $uid 用户id或者用户数据数组 - * @param boolean $temporarily 是否为临时登录,默认为临时登录以兼容以前的方法 - * @param integer $expire 过期时间 - * @return boolean - */ - public function simpleLogin($uid, $temporarily = true, $expire = 0) - { - if (is_array($uid)) { - $user = $uid; - } else { - $user = $this->db->fetchRow($this->db->select() - ->from('table.users') - ->where('uid = ?', $uid) - ->limit(1)); - } - - if (empty($user)) { - $this->pluginHandle()->simpleLoginFail($this); - return false; - } - - if (!$temporarily) { - $this->commitLogin($user, $expire); - } - - $this->push($user); - $this->_user = $user; - $this->_hasLogin = true; - - $this->pluginHandle()->simpleLoginSucceed($this, $user); - return true; - } /** * @param $user @@ -213,56 +224,45 @@ class Widget_User extends Typecho_Widget $this->db->query($this->db ->update('table.users') ->expression('logged', 'activated') - ->rows(array('authCode' => $authCode)) + ->rows(['authCode' => $authCode]) ->where('uid = ?', $user['uid'])); } /** - * 用户登出函数 - * - * @access public - * @return void - */ - public function logout() - { - $this->pluginHandle()->trigger($logoutPluggable)->logout(); - if ($logoutPluggable) { - return; - } - - Typecho_Cookie::delete('__typecho_uid'); - Typecho_Cookie::delete('__typecho_authCode'); - } - - /** - * 判断用户是否已经登录 + * 只需要提供uid或者完整user数组即可登录的方法, 多用于插件等特殊场合 * * @access public + * @param int | array $uid 用户id或者用户数据数组 + * @param boolean $temporarily 是否为临时登录,默认为临时登录以兼容以前的方法 + * @param integer $expire 过期时间 * @return boolean */ - public function hasLogin() + public function simpleLogin($uid, $temporarily = true, $expire = 0) { - if (NULL !== $this->_hasLogin) { - return $this->_hasLogin; + if (is_array($uid)) { + $user = $uid; } else { - $cookieUid = Typecho_Cookie::get('__typecho_uid'); - if (NULL !== $cookieUid) { - /** 验证登陆 */ - $user = $this->db->fetchRow($this->db->select()->from('table.users') - ->where('uid = ?', intval($cookieUid)) + $user = $this->db->fetchRow($this->db->select() + ->from('table.users') + ->where('uid = ?', $uid) ->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); } + + if (empty($user)) { + $this->pluginHandle()->simpleLoginFail($this); + return false; + } + + if (!$temporarily) { + $this->commitLogin($user, $expire); + } + + $this->push($user); + $this->_user = $user; + $this->_hasLogin = true; + + $this->pluginHandle()->simpleLoginSucceed($this, $user); + return true; } /** diff --git a/var/Widget/Users/Admin.php b/var/Widget/Users/Admin.php index 6f6a432c..9a84d8d2 100644 --- a/var/Widget/Users/Admin.php +++ b/var/Widget/Users/Admin.php @@ -43,33 +43,6 @@ class Widget_Users_Admin extends Widget_Abstract_Users */ 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; - } - /** * 执行函数 * @@ -83,18 +56,18 @@ class Widget_Users_Admin extends Widget_Abstract_Users $this->_currentPage = $this->request->get('page', 1); /** 过滤标题 */ - if (NULL != ($keywords = $this->request->keywords)) { + if (null != ($keywords = $this->request->keywords)) { $select->where('name LIKE ? OR screenName LIKE ?', - '%' . Typecho_Common::filterSearchQuery($keywords) . '%', - '%' . Typecho_Common::filterSearchQuery($keywords) . '%'); + '%' . 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); + ->page($this->_currentPage, $this->parameter->pageSize); - $this->db->fetchAll($select, array($this, 'push')); + $this->db->fetchAll($select, [$this, 'push']); } /** @@ -109,7 +82,34 @@ class Widget_Users_Admin extends Widget_Abstract_Users /** 使用盒状分页 */ $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); + $this->_currentPage, $this->parameter->pageSize, $query); $nav->render('«', '»'); } + + /** + * 仅仅输出域名和路径 + * + * @access protected + * @return string + */ + protected function ___domainPath() + { + $parts = parse_url($this->url); + return $parts['host'] . ($parts['path'] ?? null); + } + + /** + * 发布文章数 + * + * @access protected + * @return integer + */ + protected function ___postsNum() + { + return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num']) + ->from('table.contents') + ->where('table.contents.type = ?', 'post') + ->where('table.contents.status = ?', 'publish') + ->where('table.contents.authorId = ?', $this->uid))->num; + } } diff --git a/var/Widget/Users/Author.php b/var/Widget/Users/Author.php index e8e8fb44..21f35e84 100644 --- a/var/Widget/Users/Author.php +++ b/var/Widget/Users/Author.php @@ -31,7 +31,7 @@ class Widget_Users_Author extends Widget_Abstract_Users { if ($this->parameter->uid) { $this->db->fetchRow($this->select() - ->where('uid = ?', $this->parameter->uid), array($this, 'push')); + ->where('uid = ?', $this->parameter->uid), [$this, 'push']); } } } diff --git a/var/Widget/Users/Edit.php b/var/Widget/Users/Edit.php index 21dc934c..b3b0726b 100644 --- a/var/Widget/Users/Edit.php +++ b/var/Widget/Users/Edit.php @@ -20,18 +20,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ 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); - } - /** * 执行函数 * @@ -46,7 +34,7 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac /** 更新模式 */ 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')); + ->where('uid = ?', $this->request->uid)->limit(1), [$this, 'push']); if (!$this->have()) { throw new Typecho_Widget_Exception(_t('用户不存在'), 404); @@ -75,125 +63,12 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac public function userExists($uid) { $user = $this->db->fetchRow($this->db->select() - ->from('table.users') - ->where('uid = ?', $uid)->limit(1)); + ->from('table.users') + ->where('uid = ?', $uid)->limit(1)); return !empty($user); } - /** - * 生成表单 - * - * @access public - * @param string $action 表单动作 - * @return Typecho_Widget_Helper_Form - */ - public function form($action = NULL) - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-edit'), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 用户名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, _t('用户名') . ' *', _t('此用户名将作为用户登录时所用的名称.') - . '<br />' . _t('请不要与系统中现有的用户名重复.')); - $form->addInput($name); - - /** 电子邮箱地址 */ - $mail = new Typecho_Widget_Helper_Form_Element_Text('mail', NULL, NULL, _t('邮件地址') . ' *', _t('电子邮箱地址将作为此用户的主要联系方式.') - . '<br />' . _t('请不要与系统中现有的电子邮箱地址重复.')); - $form->addInput($mail); - - /** 用户昵称 */ - $screenName = new Typecho_Widget_Helper_Form_Element_Text('screenName', NULL, NULL, _t('用户昵称'), _t('用户昵称可以与用户名不同, 用于前台显示.') - . '<br />' . _t('如果你将此项留空, 将默认使用用户名.')); - $form->addInput($screenName); - - /** 用户密码 */ - $password = new Typecho_Widget_Helper_Form_Element_Password('password', NULL, NULL, _t('用户密码'), _t('为此用户分配一个密码.') - . '<br />' . _t('建议使用特殊字符与字母、数字的混编样式,以增加系统安全性.')); - $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('subscriber' => _t('关注者'), - 'contributor' => _t('贡献者'), 'editor' => _t('编辑'), 'administrator' => _t('管理员')), - NULL, _t('用户组'), _t('不同的用户组拥有不同的权限.') - . '<br />' . _t('具体的权限分配表请<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', 'btn 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('昵称已经存在')); - $screenName->addRule('xssCheck', _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; - } - /** * 增加用户 * @@ -227,6 +102,121 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac $this->response->redirect(Typecho_Common::url('manage-users.php', $this->options->adminUrl)); } + /** + * 生成表单 + * + * @access public + * @param string $action 表单动作 + * @return Typecho_Widget_Helper_Form + */ + public function form($action = null) + { + /** 构建表格 */ + $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-edit'), + Typecho_Widget_Helper_Form::POST_METHOD); + + /** 用户名称 */ + $name = new Typecho_Widget_Helper_Form_Element_Text('name', null, null, _t('用户名') . ' *', _t('此用户名将作为用户登录时所用的名称.') + . '<br />' . _t('请不要与系统中现有的用户名重复.')); + $form->addInput($name); + + /** 电子邮箱地址 */ + $mail = new Typecho_Widget_Helper_Form_Element_Text('mail', null, null, _t('邮件地址') . ' *', _t('电子邮箱地址将作为此用户的主要联系方式.') + . '<br />' . _t('请不要与系统中现有的电子邮箱地址重复.')); + $form->addInput($mail); + + /** 用户昵称 */ + $screenName = new Typecho_Widget_Helper_Form_Element_Text('screenName', null, null, _t('用户昵称'), _t('用户昵称可以与用户名不同, 用于前台显示.') + . '<br />' . _t('如果你将此项留空, 将默认使用用户名.')); + $form->addInput($screenName); + + /** 用户密码 */ + $password = new Typecho_Widget_Helper_Form_Element_Password('password', null, null, _t('用户密码'), _t('为此用户分配一个密码.') + . '<br />' . _t('建议使用特殊字符与字母、数字的混编样式,以增加系统安全性.')); + $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', [ + 'subscriber' => _t('关注者'), + 'contributor' => _t('贡献者'), 'editor' => _t('编辑'), 'administrator' => _t('管理员') + ], + null, _t('用户组'), _t('不同的用户组拥有不同的权限.') + . '<br />' . _t('具体的权限分配表请<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', 'btn 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([$this, 'screenNameExists'], _t('昵称已经存在')); + $screenName->addRule('xssCheck', _t('请不要在昵称中使用特殊字符')); + $url->addRule('url', _t('个人主页地址格式错误')); + $mail->addRule('required', _t('必须填写电子邮箱')); + $mail->addRule([$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([$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([$this, 'userExists'], _t('用户不存在')); + } + + return $form; + } + /** * 更新用户 * @@ -260,7 +250,19 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac /** 转向原页 */ $this->response->redirect(Typecho_Common::url('manage-users.php?' . - $this->getPageOffsetQuery($this->request->uid), $this->options->adminUrl)); + $this->getPageOffsetQuery($this->request->uid), $this->options->adminUrl)); + } + + /** + * 获取页面偏移的URL Query + * + * @access protected + * @param integer $uid 用户id + * @return string + */ + protected function getPageOffsetQuery($uid) + { + return 'page=' . $this->getPageOffset('uid', $uid); } /** @@ -272,7 +274,7 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac public function deleteUser() { $users = $this->request->filter('int')->getArray('uid'); - $masterUserId = $this->db->fetchObject($this->db->select(array('MIN(uid)' => 'num'))->from('table.users'))->num; + $masterUserId = $this->db->fetchObject($this->db->select(['MIN(uid)' => 'num'])->from('table.users'))->num; $deleteCount = 0; foreach ($users as $user) { @@ -287,7 +289,7 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac /** 提示信息 */ $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('用户已经删除') : _t('没有用户被删除'), - $deleteCount > 0 ? 'success' : 'notice'); + $deleteCount > 0 ? 'success' : 'notice'); /** 转向原页 */ $this->response->redirect(Typecho_Common::url('manage-users.php', $this->options->adminUrl)); diff --git a/var/Widget/Users/Profile.php b/var/Widget/Users/Profile.php index a579b270..3c13eb0a 100644 --- a/var/Widget/Users/Profile.php +++ b/var/Widget/Users/Profile.php @@ -33,56 +33,6 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface $this->request->setParam('uid', $this->user->uid); } - /** - * 生成表单 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function profileForm() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 用户昵称 */ - $screenName = new Typecho_Widget_Helper_Form_Element_Text('screenName', NULL, NULL, _t('昵称'), _t('用户昵称可以与用户名不同, 用于前台显示.') - . '<br />' . _t('如果你将此项留空, 将默认使用用户名.')); - $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 />' . _t('请不要与系统中现有的电子邮箱地址重复.')); - $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', 'btn 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('昵称已经存在')); - $screenName->addRule('xssCheck', _t('请不要在昵称中使用特殊字符')); - $url->addRule('url', _t('个人主页地址格式错误')); - $mail->addRule('required', _t('必须填写电子邮箱')); - $mail->addRule(array($this, 'mailExists'), _t('电子邮箱地址已经存在')); - $mail->addRule('email', _t('电子邮箱格式错误')); - - return $form; - } - /** * 输出表单结构 * @@ -93,30 +43,30 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface { /** 构建表格 */ $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'), - Typecho_Widget_Helper_Form::POST_METHOD); + 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 语法编辑和解析内容'), + ['0' => _t('关闭'), '1' => _t('打开')], + $this->options->markdown, _t('使用 Markdown 语法编辑和解析内容'), _t('使用 <a href="http://daringfireball.net/projects/markdown/">Markdown</a> 语法能够使您的撰写过程更加简便直观.') - . '<br />' . _t('此功能开启不会影响以前没有使用 Markdown 语法编辑的内容.')); + . '<br />' . _t('此功能开启不会影响以前没有使用 Markdown 语法编辑的内容.')); $form->addInput($markdown); $xmlrpcMarkdown = new Typecho_Widget_Helper_Form_Element_Radio('xmlrpcMarkdown', - array('0' => _t('关闭'), '1' => _t('打开')), - $this->options->xmlrpcMarkdown, _t('在 XMLRPC 接口中使用 Markdown 语法'), + ['0' => _t('关闭'), '1' => _t('打开')], + $this->options->xmlrpcMarkdown, _t('在 XMLRPC 接口中使用 Markdown 语法'), _t('对于完全支持 <a href="http://daringfireball.net/projects/markdown/">Markdown</a> 语法写作的离线编辑器, 打开此选项后将避免内容被转换为 HTML.')); $form->addInput($xmlrpcMarkdown); /** 自动保存 */ $autoSave = new Typecho_Widget_Helper_Form_Element_Radio('autoSave', - array('0' => _t('关闭'), '1' => _t('打开')), - $this->options->autoSave, _t('自动保存'), _t('自动保存功能可以更好地保护你的文章不会丢失.')); + ['0' => _t('关闭'), '1' => _t('打开')], + $this->options->autoSave, _t('自动保存'), _t('自动保存功能可以更好地保护你的文章不会丢失.')); $form->addInput($autoSave); /** 默认允许 */ - $allow = array(); + $allow = []; if ($this->options->defaultAllowComment) { $allow[] = 'comment'; } @@ -130,22 +80,49 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface } $defaultAllow = new Typecho_Widget_Helper_Form_Element_Checkbox('defaultAllow', - array('comment' => _t('可以被评论'), 'ping' => _t('可以被引用'), 'feed' => _t('出现在聚合中')), - $allow, _t('默认允许'), _t('设置你经常使用的默认允许权限')); + ['comment' => _t('可以被评论'), 'ping' => _t('可以被引用'), 'feed' => _t('出现在聚合中')], + $allow, _t('默认允许'), _t('设置你经常使用的默认允许权限')); $form->addInput($defaultAllow); /** 用户动作 */ - $do = new Typecho_Widget_Helper_Form_Element_Hidden('do', NULL, 'options'); + $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 = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置')); $submit->input->setAttribute('class', 'btn primary'); $form->addItem($submit); return $form; } + /** + * 自定义设置列表 + * + * @access public + * @return void + */ + public function personalFormList() + { + $this->widget('Widget_Plugins_List@personalPlugins', 'activated=1')->to($plugins); + while ($plugins->next()) { + if ($plugins->personalConfig) { + [$pluginFileName, $className] = Typecho_Plugin::portal($plugins->name, + $this->options->pluginDir($plugins->name)); + + $form = $this->personalForm($plugins->name, $className, $pluginFileName, $group); + if ($this->user->pass($group, true)) { + echo '<br><section id="personal-' . $plugins->name . '">'; + echo '<h3>' . $plugins->title . '</h3>'; + + $form->render(); + + echo '</section>'; + } + } + } + } + /** * 输出自定义设置选项 * @@ -160,12 +137,12 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface { /** 构建表格 */ $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'), - Typecho_Widget_Helper_Form::POST_METHOD); + 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 = call_user_func([$className, 'personalConfig'], $form); $group = $group ? $group : 'subscriber'; $options = $this->options->personalPlugin($pluginName); @@ -176,80 +153,14 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface } } - $form->addItem(new Typecho_Widget_Helper_Form_Element_Hidden('do', NULL, 'personal')); - $form->addItem(new Typecho_Widget_Helper_Form_Element_Hidden('plugin', NULL, $pluginName)); - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('保存设置')); + $form->addItem(new Typecho_Widget_Helper_Form_Element_Hidden('do', null, 'personal')); + $form->addItem(new Typecho_Widget_Helper_Form_Element_Hidden('plugin', null, $pluginName)); + $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置')); $submit->input->setAttribute('class', 'btn primary'); $form->addItem($submit); return $form; } - /** - * 自定义设置列表 - * - * @access public - * @return void - */ - public function personalFormList() - { - $this->widget('Widget_Plugins_List@personalPlugins', 'activated=1')->to($plugins); - while ($plugins->next()) { - if ($plugins->personalConfig) { - list($pluginFileName, $className) = Typecho_Plugin::portal($plugins->name, - $this->options->pluginDir($plugins->name)); - - $form = $this->personalForm($plugins->name, $className, $pluginFileName, $group); - if ($this->user->pass($group, true)) { - echo '<br><section id="personal-' . $plugins->name . '">'; - echo '<h3>' . $plugins->title . '</h3>'; - - $form->render(); - - echo '</section>'; - } - } - } - } - - /** - * 生成表单 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function passwordForm() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 用户密码 */ - $password = new Typecho_Widget_Helper_Form_Element_Password('password', NULL, NULL, _t('用户密码'), _t('为此用户分配一个密码.') - . '<br />' . _t('建议使用特殊字符与字母、数字的混编样式,以增加系统安全性.')); - $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', 'btn primary'); - $form->addItem($submit); - - $password->addRule('required', _t('必须填写密码')); - $password->addRule('minLength', _t('为了保证账户安全, 请输入至少六位的密码'), 6); - $confirm->addRule('confirm', _t('两次输入的密码不一致'), 'password'); - - return $form; - } - /** * 更新用户 * @@ -279,6 +190,56 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface $this->response->goBack(); } + /** + * 生成表单 + * + * @access public + * @return Typecho_Widget_Helper_Form + */ + public function profileForm() + { + /** 构建表格 */ + $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'), + Typecho_Widget_Helper_Form::POST_METHOD); + + /** 用户昵称 */ + $screenName = new Typecho_Widget_Helper_Form_Element_Text('screenName', null, null, _t('昵称'), _t('用户昵称可以与用户名不同, 用于前台显示.') + . '<br />' . _t('如果你将此项留空, 将默认使用用户名.')); + $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 />' . _t('请不要与系统中现有的电子邮箱地址重复.')); + $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', 'btn primary'); + $form->addItem($submit); + + $screenName->value($this->user->screenName); + $url->value($this->user->url); + $mail->value($this->user->mail); + + /** 给表单增加规则 */ + $screenName->addRule([$this, 'screenNameExists'], _t('昵称已经存在')); + $screenName->addRule('xssCheck', _t('请不要在昵称中使用特殊字符')); + $url->addRule('url', _t('个人主页地址格式错误')); + $mail->addRule('required', _t('必须填写电子邮箱')); + $mail->addRule([$this, 'mailExists'], _t('电子邮箱地址已经存在')); + $mail->addRule('email', _t('电子邮箱格式错误')); + + return $form; + } + /** * 执行更新动作 * @@ -297,16 +258,16 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface $settings['defaultAllowFeed'] = in_array('feed', $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) { + if ($this->db->fetchObject($this->db->select(['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)); + ->update(['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_Abstract_Options')->insert([ + 'name' => $name, + 'value' => $value, + 'user' => $this->user->uid + ]); } } @@ -331,8 +292,8 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface $password = $hasher->HashPassword($this->request->password); /** 更新数据 */ - $this->update(array('password' => $password), - $this->db->sql()->where('uid = ?', $this->user->uid)); + $this->update(['password' => $password], + $this->db->sql()->where('uid = ?', $this->user->uid)); /** 设置高亮 */ $this->widget('Widget_Notice')->highlight('user-' . $this->user->uid); @@ -344,6 +305,45 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface $this->response->goBack(); } + /** + * 生成表单 + * + * @access public + * @return Typecho_Widget_Helper_Form + */ + public function passwordForm() + { + /** 构建表格 */ + $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'), + Typecho_Widget_Helper_Form::POST_METHOD); + + /** 用户密码 */ + $password = new Typecho_Widget_Helper_Form_Element_Password('password', null, null, _t('用户密码'), _t('为此用户分配一个密码.') + . '<br />' . _t('建议使用特殊字符与字母、数字的混编样式,以增加系统安全性.')); + $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', 'btn primary'); + $form->addItem($submit); + + $password->addRule('required', _t('必须填写密码')); + $password->addRule('minLength', _t('为了保证账户安全, 请输入至少六位的密码'), 6); + $confirm->addRule('confirm', _t('两次输入的密码不一致'), 'password'); + + return $form; + } + /** * 更新个人设置 * @@ -360,8 +360,8 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface $activatedPlugins = $plugins['activated']; /** 获取插件入口 */ - list($pluginFileName, $className) = Typecho_Plugin::portal($this->request->plugin, - __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__); + [$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])) { @@ -381,16 +381,16 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface $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) { + if ($this->db->fetchObject($this->db->select(['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)); + ->update(['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_Abstract_Options')->insert([ + 'name' => $name, + 'value' => serialize($settings), + 'user' => $this->user->uid + ]); } } @@ -412,7 +412,7 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface public function personalConfigHandle($className, array $settings) { if (method_exists($className, 'personalConfigHandle')) { - call_user_func(array($className, 'personalConfigHandle'), $settings, false); + call_user_func([$className, 'personalConfigHandle'], $settings, false); return true; } diff --git a/var/Widget/XmlRpc.php b/var/Widget/XmlRpc.php index 172ef7c1..90cf8407 100644 --- a/var/Widget/XmlRpc.php +++ b/var/Widget/XmlRpc.php @@ -26,170 +26,22 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface * @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(); - - 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'): // 这是预留给第三方开发者的接口, 用于强行调用非所见即所得数据 - case $this->options->xmlrpcMarkdown: - $text = $content->text; - break; - default: - $text = $content->content; - break; - } - - $post = explode('<!--more-->', $text, 2); - return array( - $this->options->xmlrpcMarkdown? $post[0] : 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); - } + private $_usedWidgetNameList = []; /** * 如果这里没有重载, 每次都会被默认执行 @@ -206,78 +58,140 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface // 临时保护模块 $this->security->enable(false); - - $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' - ), - 'home_url' => array( - 'desc' => _t( '博客首页地址' ), - 'readonly' => true, - 'option' => 'siteUrl' - ), - 'login_url' => array( - 'desc' => _t( '登录地址' ), - 'readonly' => true, - 'value' => $this->options->siteUrl.'admin/login.php' - ), - 'admin_url' => array( - 'desc' => _t( '管理区域的地址' ), - 'readonly' => true, - 'value' => $this->options->siteUrl.'admin/' - ), - 'post_thumbnail' => array( - 'desc' => _t( '文章缩略图' ), - 'readonly' => true, - 'value' => false - ), + $this->_wpOptions = [ + // Read only options + 'software_name' => [ + 'desc' => _t('软件名称'), + 'readonly' => true, + 'value' => $this->options->software + ], + 'software_version' => [ + 'desc' => _t('软件版本'), + 'readonly' => true, + 'value' => $this->options->version + ], + 'blog_url' => [ + 'desc' => _t('博客地址'), + 'readonly' => true, + 'option' => 'siteUrl' + ], + 'home_url' => [ + 'desc' => _t('博客首页地址'), + 'readonly' => true, + 'option' => 'siteUrl' + ], + 'login_url' => [ + 'desc' => _t('登录地址'), + 'readonly' => true, + 'value' => $this->options->siteUrl . 'admin/login.php' + ], + 'admin_url' => [ + 'desc' => _t('管理区域的地址'), + 'readonly' => true, + 'value' => $this->options->siteUrl . 'admin/' + ], - // 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' - ) - ); + 'post_thumbnail' => [ + 'desc' => _t('文章缩略图'), + 'readonly' => true, + 'value' => false + ], + + // Updatable options + 'time_zone' => [ + 'desc' => _t('时区'), + 'readonly' => false, + 'option' => 'timezone' + ], + 'blog_title' => [ + 'desc' => _t('博客标题'), + 'readonly' => false, + 'option' => 'title' + ], + 'blog_tagline' => [ + 'desc' => _t('博客关键字'), + 'readonly' => false, + 'option' => 'description' + ], + 'date_format' => [ + 'desc' => _t('日期格式'), + 'readonly' => false, + 'option' => 'postDateFormat' + ], + 'time_format' => [ + 'desc' => _t('时间格式'), + 'readonly' => false, + 'option' => 'postDateFormat' + ], + 'users_can_register' => [ + 'desc' => _t('是否允许注册'), + 'readonly' => false, + 'option' => 'allowRegister' + ] + ]; + } + + /** + * 获取pageId指定的page + * about wp xmlrpc api, you can see http://codex.wordpress.org/XML-RPC + * + * @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*/ + [$excerpt, $more] = $this->getPostExtended($page); + + $pageStruct = [ + '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' => [], + 'wp_page_template' => $page->template + ]; + + return $pageStruct; } /** @@ -304,65 +218,100 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface } /** - * 获取pageId指定的page - * about wp xmlrpc api, you can see http://codex.wordpress.org/XML-RPC + * 代理工厂方法,将类静态化放置到列表中 * - * @param int $blogId - * @param int $pageId - * @param string $userName - * @param string $password * @access public - * @return struct $pageStruct + * @param string $alias 组件别名 + * @param mixed $params 传递的参数 + * @param mixed $request 前端参数 + * @param boolean $enableResponse 是否允许http回执 + * @return object + * @throws Typecho_Exception */ - public function wpGetPage($blogId, $pageId, $userName, $password) + private function singletonWidget($alias, $params = null, $request = null, $enableResponse = true) { - /** 检查权限 */ - if (!$this->checkAccess($userName, $password)) { - return $this->error; + $this->_usedWidgetNameList[] = $alias; + return Typecho_Widget::widget($alias, $params, $request, $enableResponse); + } + + /** + * 获取扩展字段 + * + * @access private + * @param Widget_Abstract_Contents $content + * @return array + */ + private function getPostExtended(Widget_Abstract_Contents $content) + { + //根据客户端显示来判断是否显示html代码 + $agent = $this->request->getAgent(); + + 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'): // 这是预留给第三方开发者的接口, 用于强行调用非所见即所得数据 + case $this->options->xmlrpcMarkdown: + $text = $content->text; + break; + default: + $text = $content->content; + break; } - /** 获取页面 */ - 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()); + $post = explode('<!--more-->', $text, 2); + return [ + $this->options->xmlrpcMarkdown ? $post[0] : 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'; + } + } elseif ('page' == $type) { + switch ($status) { + case 'publish': + case 'draft': + case 'private': + return $status; + default: + return 'publish'; + } + } elseif ('comment' == $type) { + switch ($status) { + case 'publish': + case 'approved': + return 'approve'; + case 'waiting': + return 'hold'; + case 'spam': + return $status; + default: + return 'approve'; + } } - /** 对文章内容做截取处理,以获得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; + return ''; } /** @@ -382,40 +331,40 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface /** 过滤type为page的contents */ /** 同样需要flush一下, 需要取出所有status的页面 */ - $pages = $this->singletonWidget('Widget_Contents_Page_Admin', NULL, 'status=all'); + $pages = $this->singletonWidget('Widget_Contents_Page_Admin', null, 'status=all'); /** 初始化要返回的数据结构 */ - $pageStructs = array(); + $pageStructs = []; 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' => intval($pages->cid), - 'page_status' => $this->typechoToWordpressStatus(($pages->hasSaved || 'page_draft' == $pages->type) ? 'draft' : $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' => intval($pages->order), //meta是描述字段, 在page时表示顺序 - 'wp_author_id' => $pages->authorId, + [$excerpt, $more] = $this->getPostExtended($pages); + $pageStructs[] = [ + 'dateCreated' => new IXR_Date($this->options->timezone + $pages->created), + 'userid' => $pages->authorId, + 'page_id' => intval($pages->cid), + 'page_status' => $this->typechoToWordpressStatus(($pages->hasSaved || 'page_draft' == $pages->type) ? 'draft' : $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' => intval($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 - ); + 'date_created_gmt' => new IXR_Date($pages->created), + 'custom_fields' => [], + 'wp_page_template' => $pages->template + ]; } return $pageStructs; @@ -441,6 +390,223 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $this->mwNewPost($blogId, $userName, $password, $content, $publish); } + /** + * MetaWeblog API + * about MetaWeblog API, you can see http://www.xmlrpc.com/metaWeblogApi + * + * @param int $blogId + * @param string $userName + * @param string $password + * @param mixed $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 = []; + $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']; + } elseif (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'] = []; + + 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, ['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'; + $input['markdown'] = $this->options->xmlrpcMarkdown; + + /** 调整状态 */ + if (isset($content["{$type}_status"])) { + $status = $this->wordpressToTypechoStatus($content["{$type}_status"], $type); + $input['visibility'] = isset($content["visibility"]) ? $content["visibility"] : $status; + 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'), [$this, 'filter']); + + if (!empty($unattached)) { + foreach ($unattached as $attach) { + if (false !== strpos($input['text'], $attach['attachment']->url)) { + if (!isset($input['attachment'])) { + $input['attachment'] = []; + } + + $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()); + } + } + + /** + * 添加一个新的分类 + * + * @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['parent'] = isset($category['parent_id']) ? $category['parent_id'] : + (isset($category['parent']) ? $category['parent'] : 0); + $input['description'] = isset($category['description']) ? $category['description'] : $category['name']; + $input['do'] = 'insert'; + + /** 调用已有组件 */ + try { + /** 插入 */ + $categoryWidget = $this->singletonWidget('Widget_Metas_Category_Edit', null, $input, false); + $categoryWidget->action(); + return $categoryWidget->mid; + } catch (Typecho_Widget_Exception $e) { + return new IXR_Error($e->getCode(), $e->getMessage()); + } + + return new IXR_Error(403, _t('无法添加分类')); + } + + /** + * 将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'; + } + } elseif ('page' == $type) { + switch ($status) { + case 'publish': + case 'draft': + case 'private': + return $status; + default: + return 'publish'; + } + } elseif ('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 ''; + } + /** * 删除pageId指定的page * @@ -460,7 +626,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface /** 删除页面 */ try { /** 此组件会进行复杂的权限检测 */ - $this->singletonWidget('Widget_Contents_Page_Edit', NULL, "cid={$pageId}", false)->deletePage(); + $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()); @@ -487,9 +653,25 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $this->mwEditPost($pageId, $userName, $password, $content, $publish); } + /** + * 编辑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); + } /** - * 编辑postId指定的post + * 编辑postId指定的post * * @param int $blogId * @param string $userName @@ -533,18 +715,18 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password, 'editor')) { return ($this->error); } - $pages = $this->singletonWidget('Widget_Contents_Page_Admin', NULL, 'status=all'); + $pages = $this->singletonWidget('Widget_Contents_Page_Admin', null, 'status=all'); /**初始化*/ - $pageStructs = array(); + $pageStructs = []; 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', - ); + $pageStructs[] = [ + '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; @@ -569,55 +751,18 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $select = $this->db->select('table.users.uid', 'table.users.name', 'table.users.screenName')->from('table.users'); $authors = $this->db->fetchAll($select); - $authorStructs = array(); + $authorStructs = []; foreach ($authors as $author) { - $authorStructs[] = array( - 'user_id' => $author['uid'], - 'user_login' => $author['name'], - 'display_name' => $author['screenName'] - ); + $authorStructs[] = [ + '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['parent'] = isset($category['parent_id']) ? $category['parent_id'] : - (isset($category['parent']) ? $category['parent'] : 0); - $input['description'] = isset($category['description']) ? $category['description'] : $category['name']; - $input['do'] = 'insert'; - - /** 调用已有组件 */ - try { - /** 插入 */ - $categoryWidget = $this->singletonWidget('Widget_Metas_Category_Edit', NULL, $input, false); - $categoryWidget->action(); - return $categoryWidget->mid; - } catch (Typecho_Widget_Exception $e) { - return new IXR_Error($e->getCode(), $e->getMessage()); - } - - return new IXR_Error(403, _t('无法添加分类')); - } - /** * 获取由给定的string开头的链接组成的数组 * @@ -646,20 +791,20 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $categories = $this->db->fetchAll($select); /** 初始化categorise数组*/ - $categoryStructs = array(); + $categoryStructs = []; foreach ($categories as $category) { - $categoryStructs[] = array( - 'category_id' => $category['mid'], + $categoryStructs[] = [ + 'category_id' => $category['mid'], 'category_name' => $category['name'], - ); + ]; } return $categoryStructs; } - + /** * 获取用户 - * + * * @access public * @param string $userName 用户名 * @param string $password 密码 @@ -672,20 +817,20 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface 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 - ); + $struct = []; + $struct[] = [ + '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 string $userName 用户名 * @param string $password 密码 @@ -698,25 +843,25 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface return $this->error; } - $struct = array( - 'user_id' => $this->user->uid, - 'username' => $this->user->name, - 'first_name' => '', - 'last_name' => '', - 'registered' => new IXR_Date($this->options->timezone + $this->user->created), - 'bio' => '', - 'email' => $this->user->mail, - 'nickname' => $this->user->screenName, - 'url' => $this->user->url, - 'display_name' => $this->user->screenName, - 'roles' => $this->user->group - ); + $struct = [ + 'user_id' => $this->user->uid, + 'username' => $this->user->name, + 'first_name' => '', + 'last_name' => '', + 'registered' => new IXR_Date($this->options->timezone + $this->user->created), + 'bio' => '', + 'email' => $this->user->mail, + 'nickname' => $this->user->screenName, + 'url' => $this->user->url, + 'display_name' => $this->user->screenName, + 'roles' => $this->user->group + ]; return $struct; } - + /** * 获取标签列表 - * + * * @access public * @param integer $blogId * @param string $userName @@ -729,27 +874,27 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - - $struct = array(); + + $struct = []; $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 - ); + $struct[] = [ + '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 @@ -763,18 +908,18 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password, 'editor')) { return $this->error; } - + try { - $this->singletonWidget('Widget_Metas_Category_Edit', NULL, 'do=delete&mid=' . intval($categoryId), false); + $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 @@ -788,21 +933,20 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - - $stat = $this->singletonWidget('Widget_Stat', NULL, 'cid=' . intval($postId), false); - - return array( + + $stat = $this->singletonWidget('Widget_Stat', null, 'cid=' . intval($postId), false); + + return [ 'approved' => $stat->currentPublishedCommentsNum, 'awaiting_moderation' => $stat->currentWaitingCommentsNum, 'spam' => $stat->currentSpamCommentsNum, 'total_comments' => $stat->currentCommentsNum - ); + ]; } - /** * 获取文章类型列表 - * + * * @access public * @param integer $blogId * @param string $userName @@ -815,15 +959,15 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - - return array( + + return [ 'standard' => _t('标准') - ); + ]; } - + /** * 获取文章状态列表 - * + * * @access public * @param integer $blogId * @param string $userName @@ -836,17 +980,17 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - - return array( - 'draft' => _t('草稿'), - 'pending' => _t('待审核'), - 'publish' => _t('已发布') - ); + + return [ + 'draft' => _t('草稿'), + 'pending' => _t('待审核'), + 'publish' => _t('已发布') + ]; } - + /** * 获取页面状态列表 - * + * * @access public * @param integer $blogId * @param string $userName @@ -859,18 +1003,16 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password, 'editor')) { return $this->error; } - - return array( - 'draft' => _t('草稿'), - 'publish' => _t('已发布') - ); + + return [ + 'draft' => _t('草稿'), + 'publish' => _t('已发布') + ]; } - - /** * 获取评论状态列表 - * + * * @access public * @param integer $blogId * @param string $userName @@ -883,17 +1025,17 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - - return array( - 'hold' => _t('待审核'), - 'approve' => _t('显示'), - 'spam' => _t('垃圾') - ); + + return [ + 'hold' => _t('待审核'), + 'approve' => _t('显示'), + 'spam' => _t('垃圾') + ]; } - + /** * 获取页面模板 - * + * * @access public * @param integer $blogId * @param string $userName @@ -906,16 +1048,16 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface 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 @@ -923,18 +1065,18 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface * @param array $options * @return array */ - public function wpGetOptions($blogId, $userName, $password, $options = array()) + public function wpGetOptions($blogId, $userName, $password, $options = []) { /** 检查权限*/ if (!$this->checkAccess($userName, $password, 'administrator')) { return $this->error; } - - $struct = array(); + + $struct = []; if (empty($options)) { $options = array_keys($this->_wpOptions); } - + foreach ($options as $option) { if (isset($this->_wpOptions[$option])) { $struct[$option] = $this->_wpOptions[$option]; @@ -944,13 +1086,13 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface } } } - + return $struct; } - + /** * 设置系统选项 - * + * * @access public * @param integer $blogId * @param string $userName @@ -958,14 +1100,14 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface * @param array $options * @return array */ - public function wpSetOptions($blogId, $userName, $password, $options = array()) + public function wpSetOptions($blogId, $userName, $password, $options = []) { /** 检查权限*/ if (!$this->checkAccess($userName, $password, 'administrator')) { return $this->error; } - - $struct = array(); + + $struct = []; foreach ($options as $option => $value) { if (isset($this->_wpOptions[$option])) { $struct[$option] = $this->_wpOptions[$option]; @@ -973,23 +1115,23 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $struct[$option]['value'] = $this->options->{$struct[$option]['option']}; unset($struct[$option]['option']); } - + if (!$this->_wpOptions[$option]['readonly'] && isset($this->_wpOptions[$option]['option'])) { if ($this->db->query($this->db->update('table.options') - ->rows(array('value' => $value)) - ->where('name = ?', $this->_wpOptions[$option]['option'])) > 0) { + ->rows(['value' => $value]) + ->where('name = ?', $this->_wpOptions[$option]['option'])) > 0) { $struct[$option]['value'] = $value; } } } } - + return $struct; } - + /** * 获取评论 - * + * * @access public * @param integer $blogId * @param string $userName @@ -1003,38 +1145,38 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - - $comment = $this->singletonWidget('Widget_Comments_Edit', NULL, 'do=get&coid=' . intval($commentId), false); - + + $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 - ); + + return [ + '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 @@ -1048,56 +1190,56 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - - $input = array(); + + $input = []; if (!empty($struct['status'])) { $input['status'] = $this->wordpressToTypechoStatus($struct['status'], 'comment'); } 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(); - + $commentsStruct = []; + 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 - ); + $commentsStruct[] = [ + '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 @@ -1111,21 +1253,21 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface 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('无法编辑此评论')); } return intval($this->singletonWidget('Widget_Abstract_Comments')->delete($where)) > 0; } - + /** * 编辑评论 - * + * * @access public * @param integer $blogId * @param string $userName @@ -1140,53 +1282,53 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface 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(); - + + $input = []; + 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); - + + $result = $commentWidget->update((array)$input, $where); + if (!$result) { return new IXR_Error(404, _t('评论不存在')); } - + return true; } - + /** * 更新评论 - * + * * @access public * @param integer $blogId * @param string $userName @@ -1201,7 +1343,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - + if (is_numeric($path)) { $post = $this->singletonWidget('Widget_Archive', 'type=single', 'cid=' . $path, false); } else { @@ -1209,52 +1351,50 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $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 = []; $input['permalink'] = $post->pathinfo; - $input['type'] = 'comment'; - + $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 { - $commentWidget = $this->singletonWidget('Widget_Feedback', 'checkReferer=false', $input, false); + $commentWidget = $this->singletonWidget('Widget_Feedback', 'checkReferer=false', $input, false); $commentWidget->action(); return intval($commentWidget->coid); } catch (Typecho_Exception $e) { return new IXR_Error(500, $e->getMessage()); } - + return new IXR_Error(403, _t('无法添加评论')); } - - /** * 获取媒体文件 - * + * * @access public * @param integer $blogId * @param string $userName @@ -1268,9 +1408,9 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - - $input = array(); + + $input = []; if (!empty($struct['parent_id'])) { $input['parent'] = $struct['parent_id']; @@ -1279,42 +1419,42 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!empty($struct['mime_type'])) { $input['mime'] = $struct['mime_type']; } - + $pageSize = 10; if (!empty($struct['number'])) { $pageSize = abs(intval($struct['number'])); } - + if (!empty($struct['offset'])) { $input['page'] = abs(intval($struct['offset'])) + 1; } - - $attachments = $this->singletonWidget('Widget_Contents_Attachment_Admin', 'pageSize=' . $pageSize, $input, false); - $attachmentsStruct = array(); - - while ($attachments->next()) { - $attachmentsStruct[] = array( - 'attachment_id' => $attachments->cid, - 'date_created_gmt' => new IXR_Date($this->options->timezone + $attachments->created), - 'parent' => $attachments->parent, - 'link' => $attachments->attachment->url, - 'title' => $attachments->title, - 'caption' => $attachments->slug, - 'description' => $attachments->attachment->description, - 'metadata' => array( - 'file' => $attachments->attachment->path, - 'size' => $attachments->attachment->size, - ), - 'thumbnail' => $attachments->attachment->url, - ); + $attachments = $this->singletonWidget('Widget_Contents_Attachment_Admin', 'pageSize=' . $pageSize, $input, false); + $attachmentsStruct = []; + + while ($attachments->next()) { + $attachmentsStruct[] = [ + 'attachment_id' => $attachments->cid, + 'date_created_gmt' => new IXR_Date($this->options->timezone + $attachments->created), + 'parent' => $attachments->parent, + 'link' => $attachments->attachment->url, + 'title' => $attachments->title, + 'caption' => $attachments->slug, + 'description' => $attachments->attachment->description, + 'metadata' => [ + 'file' => $attachments->attachment->path, + 'size' => $attachments->attachment->size, + ], + 'thumbnail' => $attachments->attachment->url, + + ]; } return $attachmentsStruct; } /** * 获取媒体文件 - * + * * @access public * @param integer $blogId * @param string $userName @@ -1328,175 +1468,27 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (!$this->checkAccess($userName, $password)) { return $this->error; } - - - $attachment = $this->singletonWidget('Widget_Contents_Attachment_Edit', NULL, "cid={$attachmentId}"); - $struct = array( - 'attachment_id' => $attachment->cid, - 'date_created_gmt' => new IXR_Date($this->options->timezone + $attachment->created), - 'parent' => $attachment->parent, - 'link' => $attachment->attachment->url, - 'title' => $attachment->title, - 'caption' => $attachment->slug, - 'description' => $attachment->attachment->description, - 'metadata' => array( - 'file' => $attachment->attachment->path, - 'size' => $attachment->attachment->size, - ), - 'thumbnail' => $attachment->attachment->url, - ); + + $attachment = $this->singletonWidget('Widget_Contents_Attachment_Edit', null, "cid={$attachmentId}"); + $struct = [ + 'attachment_id' => $attachment->cid, + 'date_created_gmt' => new IXR_Date($this->options->timezone + $attachment->created), + 'parent' => $attachment->parent, + 'link' => $attachment->attachment->url, + 'title' => $attachment->title, + 'caption' => $attachment->slug, + 'description' => $attachment->attachment->description, + 'metadata' => [ + 'file' => $attachment->attachment->path, + 'size' => $attachment->attachment->size, + ], + 'thumbnail' => $attachment->attachment->url, + + ]; return $struct; } - - - /** - * MetaWeblog API - * about MetaWeblog API, you can see http://www.xmlrpc.com/metaWeblogApi - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param mixed $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'; - $input['markdown'] = $this->options->xmlrpcMarkdown; - - /** 调整状态 */ - if (isset($content["{$type}_status"])) { - $status = $this->wordpressToTypechoStatus($content["{$type}_status"], $type); - $input['visibility'] = isset($content["visibility"]) ? $content["visibility"] : $status; - 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 * @@ -1513,42 +1505,42 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface } try { - $post = $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}"); + $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); + [$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 - ); - + $postStruct = [ + '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' => [], + 'sticky' => 0 + ]; + return $postStruct; } @@ -1570,46 +1562,46 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $posts = $this->singletonWidget('Widget_Contents_Post_Admin', "pageSize={$postsNum}", 'status=all'); - $postStructs = array(); + $postStructs = []; /** 如果这个post存在则输出,否则输出错误 */ while ($posts->next()) { /** 对文章内容做截取处理,以获得description和text_more*/ - list($excerpt, $more) = $this->getPostExtended($posts); + [$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, - 'wp_more_text' => $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->hasSaved || 'post_draft' == $posts->type) ? 'draft' : $posts->status, 'post'), - 'custom_fields' => array(), - 'wp_post_format' => 'standard', - 'date_modified' => new IXR_Date($this->options->timezone + $posts->modified), - 'date_modified_gmt' => new IXR_Date($posts->modified), - 'wp_post_thumbnail' => '', - 'sticky' => 0 - ); + $postStructs[] = [ + '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, + 'wp_more_text' => $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->hasSaved || 'post_draft' == $posts->type) ? 'draft' : $posts->status, 'post'), + 'custom_fields' => [], + 'wp_post_format' => 'standard', + 'date_modified' => new IXR_Date($this->options->timezone + $posts->modified), + 'date_modified_gmt' => new IXR_Date($posts->modified), + 'wp_post_thumbnail' => '', + 'sticky' => 0 + ]; } return $postStructs; @@ -1633,17 +1625,17 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $categories = $this->singletonWidget('Widget_Metas_Category_List'); /** 初始化category数组*/ - $categoryStructs = array(); + $categoryStructs = []; while ($categories->next()) { - $categoryStructs[] = array( - 'categoryId' => $categories->mid, - 'parentId' => $categories->parent, - 'categoryName' => $categories->name, - 'categoryDescription' => $categories->description, - 'description' => $categories->name, - 'htmlUrl' => $categories->permalink, - 'rssUrl' => $categories->feedUrl, - ); + $categoryStructs[] = [ + 'categoryId' => $categories->mid, + 'parentId' => $categories->parent, + 'categoryName' => $categories->name, + 'categoryDescription' => $categories->description, + 'description' => $categories->name, + 'htmlUrl' => $categories->permalink, + 'rssUrl' => $categories->feedUrl, + ]; } return $categoryStructs; @@ -1671,27 +1663,27 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface return new 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 - )); + $insertId = $this->insert([ + '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')); + ->where('table.contents.type = ?', 'attachment'), [$this, 'push']); /** 增加插件接口 */ $this->pluginHandle()->upload($this); - return array( + return [ 'file' => $this->attachment->name, - 'url' => $this->attachment->url - ); + 'url' => $this->attachment->url + ]; } } @@ -1715,15 +1707,15 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $posts = $this->singletonWidget('Widget_Contents_Post_Admin', "pageSize=$postsNum", 'status=all'); /**初始化*/ - $postTitleStructs = array(); + $postTitleStructs = []; 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) - ); + $postTitleStructs[] = [ + '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; @@ -1747,12 +1739,12 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $categories = $this->singletonWidget('Widget_Metas_Category_List'); /** 初始化categorise数组*/ - $categoryStructs = array(); + $categoryStructs = []; while ($categories->next()) { - $categoryStructs[] = array( - 'categoryId' => $categories->mid, + $categoryStructs[] = [ + 'categoryId' => $categories->mid, 'categoryName' => $categories->name, - ); + ]; } return $categoryStructs; } @@ -1773,19 +1765,19 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface } try { - $post = $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}"); + $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(); + $categories = []; foreach ($post->categories as $category) { - $categories[] = array( - 'categoryName' => $category['name'], - 'categoryId' => $category['mid'], - 'isPrimary' => true - ); + $categories[] = [ + 'categoryName' => $category['name'], + 'categoryId' => $category['mid'], + 'isPrimary' => true + ]; } return $categories; } @@ -1807,13 +1799,13 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface } try { - $post = $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}"); + $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); + 'publish' == $post->status); return true; } @@ -1836,13 +1828,13 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface $select = $this->select()->where('table.contents.cid = ? AND table.contents.type = ?', $postId, 'post')->limit(1); /** 提交查询 */ - $post = $this->db->fetchRow($select, array($this, 'push')); + $post = $this->db->fetchRow($select, [$this, 'push']); if ($this->authorId != $this->user->uid && !$this->checkAccess($userName, $password, 'administrator')) { return new IXR_Error(403, '权限不足.'); } /** 暂时只做成发布*/ - $content = array(); + $content = []; $this->update($content, $this->db->sql()->where('table.contents.cid = ?', $postId)); @@ -1863,15 +1855,15 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface return $this->error; } - $struct = array(); - $struct[] = array( - 'isAdmin' => $this->user->pass('administrator', true), - 'url' => $this->options->siteUrl, - 'blogid' => '1', + $struct = []; + $struct[] = [ + 'isAdmin' => $this->user->pass('administrator', true), + 'url' => $this->options->siteUrl, + 'blogid' => '1', 'blogName' => $this->options->title, - 'xmlrpc' => $this->options->xmlRpcUrl - ); - + 'xmlrpc' => $this->options->xmlRpcUrl + ]; + return $struct; } @@ -1890,15 +1882,15 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface return $this->error; } - $struct = array( - 'nickname' => $this->user->screenName, - 'userid' => $this->user->uid, - 'url' => $this->user->url, - 'email' => $this->user->mail, - 'lastname' => '', + $struct = [ + 'nickname' => $this->user->screenName, + 'userid' => $this->user->uid, + 'url' => $this->user->url, + 'email' => $this->user->mail, + 'lastname' => '', 'firstname' => '' - ); - + ]; + return $struct; } @@ -1919,23 +1911,23 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface } try { - $post = $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}"); + $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 - ); + $struct = [ + 'userid' => $post->authorId, + 'dateCreated' => new IXR_Date($this->options->timezone + $post->created), + 'content' => $content, + 'postid' => $post->cid + ]; return $struct; } @@ -1955,7 +1947,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface return $this->error; } try { - $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}", false)->deletePost(); + $this->singletonWidget('Widget_Contents_Post_Edit', null, "cid={$postId}", false)->deletePost(); } catch (Typecho_Widget_Exception $e) { return new IXR_Error($e->getCode(), $e->getMessage()); } @@ -1979,23 +1971,23 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface //todo:限制数量 $posts = $this->singletonWidget('Widget_Contents_Post_Admin', "pageSize=$postsNum", 'status=all'); - $postStructs = array(); + $postStructs = []; 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, - ); + $struct = [ + 'userid' => $posts->authorId, + 'dateCreated' => new IXR_Date($this->options->timezone + $posts->created), + 'content' => $content, + 'postid' => $posts->cid, + ]; $postStructs[] = $struct; } - if (NULL == $postStructs) { + if (null == $postStructs) { return new IXR_Error('404', '没有任何文章'); } return $postStructs; @@ -2056,7 +2048,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface /** 检查源地址是否合法 */ $params = parse_url($source); - if (false === $params || !in_array($params['scheme'], array('http', 'https'))) { + if (false === $params || !in_array($params['scheme'], ['http', 'https'])) { return new IXR_Error(16, _t('源地址服务器错误')); } @@ -2074,9 +2066,9 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface 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; + $pingNum = $this->db->fetchObject($this->db->select(['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) { /** 检查源地址是否存在*/ @@ -2122,8 +2114,8 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface foreach ($lines as $line) { $line = trim($line); - if (NULL != $line) { - if (preg_match("|]*href=[\"']{$pregLink}[\"'][^>]*>(.*?)|",$line)) { + if (null != $line) { + if (preg_match("|]*href=[\"']{$pregLink}[\"'][^>]*>(.*?)|", $line)) { if (strlen($line) > strlen($finalText)) { /** 也要干掉,*/ $finalText = Typecho_Common::stripTags($line); @@ -2133,24 +2125,24 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface } /** 截取一段字*/ - if (NULL == trim($finalText)) { + 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->time, - 'agent' => $this->request->getAgent(), - 'ip' => $this->request->getIp(), - 'author' => Typecho_Common::subStr($finalTitle, 0, 150, '...'), - 'url' => Typecho_Common::safeUrl($source), - 'text' => $finalText, - 'ownerId' => $post->author->uid, - 'type' => 'pingback', - 'status' => $this->options->commentsRequireModeration ? 'waiting' : 'approved' - ); + $pingback = [ + 'cid' => $post->cid, + 'created' => $this->options->time, + 'agent' => $this->request->getAgent(), + 'ip' => $this->request->getIp(), + 'author' => Typecho_Common::subStr($finalTitle, 0, 150, '...'), + '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); @@ -2174,10 +2166,10 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface return new IXR_Error(33, _t('这个目标地址不存在')); } } - + /** * 回收变量 - * + * * @access public * @param string $methodName 方法 * @return void @@ -2206,7 +2198,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface if (isset($this->request->rsd)) { echo -<< @@ -2222,9 +2214,9 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface EOF; - } else if (isset($this->request->wlw)) { + } elseif (isset($this->request->wlw)) { echo -<< @@ -2261,81 +2253,81 @@ EOF; EOF; } else { - $api = array( + $api = [ /** 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'), - + 'wp.getPage' => [$this, 'wpGetPage'], + 'wp.getPages' => [$this, 'wpGetPages'], + 'wp.newPage' => [$this, 'wpNewPage'], + 'wp.deletePage' => [$this, 'wpDeletePage'], + 'wp.editPage' => [$this, 'wpEditPage'], + 'wp.getPageList' => [$this, 'wpGetPageList'], + 'wp.getAuthors' => [$this, 'wpGetAuthors'], + 'wp.getCategories' => [$this, 'mwGetCategories'], + 'wp.newCategory' => [$this, 'wpNewCategory'], + 'wp.suggestCategories' => [$this, 'wpSuggestCategories'], + 'wp.uploadFile' => [$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'), + 'wp.getUsersBlogs' => [$this, 'wpGetUsersBlogs'], + 'wp.getTags' => [$this, 'wpGetTags'], + 'wp.deleteCategory' => [$this, 'wpDeleteCategory'], + 'wp.getCommentCount' => [$this, 'wpGetCommentCount'], + 'wp.getPostStatusList' => [$this, 'wpGetPostStatusList'], + 'wp.getPageStatusList' => [$this, 'wpGetPageStatusList'], + 'wp.getPageTemplates' => [$this, 'wpGetPageTemplates'], + 'wp.getOptions' => [$this, 'wpGetOptions'], + 'wp.setOptions' => [$this, 'wpSetOptions'], + 'wp.getComment' => [$this, 'wpGetComment'], + 'wp.getComments' => [$this, 'wpGetComments'], + 'wp.deleteComment' => [$this, 'wpDeleteComment'], + 'wp.editComment' => [$this, 'wpEditComment'], + 'wp.newComment' => [$this, 'wpNewComment'], + 'wp.getCommentStatusList' => [$this, 'wpGetCommentStatusList'], /** New Wordpress API after 2.9.2 */ - 'wp.getProfile' => array($this, 'wpGetProfile'), - 'wp.getPostFormats' => array($this, 'wpGetPostFormats'), - 'wp.getMediaLibrary' => array($this, 'wpGetMediaLibrary'), - 'wp.getMediaItem' => array($this, 'wpGetMediaItem'), - 'wp.editPost' => array($this, 'wpEditPost'), + 'wp.getProfile' => [$this, 'wpGetProfile'], + 'wp.getPostFormats' => [$this, 'wpGetPostFormats'], + 'wp.getMediaLibrary' => [$this, 'wpGetMediaLibrary'], + 'wp.getMediaItem' => [$this, 'wpGetMediaItem'], + 'wp.editPost' => [$this, 'wpEditPost'], /** 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'), + 'blogger.getUsersBlogs' => [$this, 'bloggerGetUsersBlogs'], + 'blogger.getUserInfo' => [$this, 'bloggerGetUserInfo'], + 'blogger.getPost' => [$this, 'bloggerGetPost'], + 'blogger.getRecentPosts' => [$this, 'bloggerGetRecentPosts'], + 'blogger.getTemplate' => [$this, 'bloggerGetTemplate'], + 'blogger.setTemplate' => [$this, 'bloggerSetTemplate'], + 'blogger.deletePost' => [$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.newPost' => [$this, 'mwNewPost'], + 'metaWeblog.editPost' => [$this, 'mwEditPost'], + 'metaWeblog.getPost' => [$this, 'mwGetPost'], + 'metaWeblog.getRecentPosts' => [$this, 'mwGetRecentPosts'], + 'metaWeblog.getCategories' => [$this, 'mwGetCategories'], + 'metaWeblog.newMediaObject' => [$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'), + 'metaWeblog.deletePost' => [$this, 'bloggerDeletePost'], + 'metaWeblog.getTemplate' => [$this, 'bloggerGetTemplate'], + 'metaWeblog.setTemplate' => [$this, 'bloggerSetTemplate'], + 'metaWeblog.getUsersBlogs' => [$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'), + 'mt.getCategoryList' => [$this, 'mtGetCategoryList'], + 'mt.getRecentPostTitles' => [$this, 'mtGetRecentPostTitles'], + 'mt.getPostCategories' => [$this, 'mtGetPostCategories'], + 'mt.setPostCategories' => [$this, 'mtSetPostCategories'], + 'mt.publishPost' => [$this, 'mtPublishPost'], /** PingBack */ - 'pingback.ping' => array($this,'pingbackPing'), + 'pingback.ping' => [$this, 'pingbackPing'], // 'pingback.extensions.getPingbacks' => array($this,'pingbackExtensionsGetPingbacks'), - + /** hook after */ - 'hook.afterCall' => array($this, 'hookAfterCall'), - ); + 'hook.afterCall' => [$this, 'hookAfterCall'], + ]; if (1 == $this->options->allowXmlRpc) { unset($api['pingback.ping']);