still working on it

This commit is contained in:
joyqi 2021-08-30 14:52:52 +08:00
parent 93b5656109
commit e15c2966a9
43 changed files with 1024 additions and 753 deletions

View File

@ -10,6 +10,7 @@ namespace PHPSTORM_META {
exitPoint(\Typecho\Widget\Response::throwFile());
exitPoint(\Typecho\Widget\Response::throwJson());
exitPoint(\Typecho\Widget\Response::throwXml());
exitPoint(\Typecho\Widget\Response::goBack());
override(\Widget\Options::__get(0), map([
'feedUrl' => string,

View File

@ -12,14 +12,14 @@ if (!defined('__TYPECHO_ROOT_DIR__') && !@include_once __DIR__ . '/../config.inc
}
/** 初始化组件 */
\Typecho\Widget::widget('Widget_Init');
\Widget\Init::alloc();
/** 注册一个初始化插件 */
\Typecho\Plugin::factory('admin/common.php')->begin();
\Typecho\Widget::widget('Widget_Options')->to($options);
\Typecho\Widget::widget('Widget_User')->to($user);
\Typecho\Widget::widget('Widget_Security')->to($security);
\Widget\Options::alloc()->to($options);
\Widget\User::alloc()->to($user);
\Widget\Security::alloc()->to($security);
\Typecho\Widget::widget('Widget_Menu')->to($menu);
/** 初始化上下文 */

View File

@ -77,6 +77,167 @@ function install_is_cli(): bool
return \Typecho\Request::getInstance()->isCli();
}
/**
* get default router
*
* @return string[][]
*/
function install_get_default_routers(): array
{
return [
'index' =>
[
'url' => '/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'archive' =>
[
'url' => '/blog/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'do' =>
[
'url' => '/action/[action:alpha]',
'widget' => '\Widget\Action',
'action' => 'action',
],
'post' =>
[
'url' => '/archives/[cid:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'attachment' =>
[
'url' => '/attachment/[cid:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'category' =>
[
'url' => '/category/[slug]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'tag' =>
[
'url' => '/tag/[slug]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'author' =>
[
'url' => '/author/[uid:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'search' =>
[
'url' => '/search/[keywords]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'index_page' =>
[
'url' => '/page/[page:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'archive_page' =>
[
'url' => '/blog/page/[page:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'category_page' =>
[
'url' => '/category/[slug]/[page:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'tag_page' =>
[
'url' => '/tag/[slug]/[page:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'author_page' =>
[
'url' => '/author/[uid:digital]/[page:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'search_page' =>
[
'url' => '/search/[keywords]/[page:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'archive_year' =>
[
'url' => '/[year:digital:4]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'archive_month' =>
[
'url' => '/[year:digital:4]/[month:digital:2]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'archive_day' =>
[
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'archive_year_page' =>
[
'url' => '/[year:digital:4]/page/[page:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'archive_month_page' =>
[
'url' => '/[year:digital:4]/[month:digital:2]/page/[page:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'archive_day_page' =>
[
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'comment_page' =>
[
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => '\Widget\Archive',
'action' => 'render',
],
'feed' =>
[
'url' => '/feed[feed:string:0]',
'widget' => '\Widget\Archive',
'action' => 'feed',
],
'feedback' =>
[
'url' => '[permalink:string]/[type:alpha]',
'widget' => '\Widget\Feedback',
'action' => 'action',
],
'page' =>
[
'url' => '/[slug].html',
'widget' => '\Widget\Archive',
'action' => 'render',
],
];
}
/**
* list all default options
*
@ -142,7 +303,7 @@ function install_get_default_options(): array
'commentsAvatar' => 1,
'commentsAvatarRating' => 'G',
'commentsAntiSpam' => 1,
'routingTable' => 'a:25:{s:5:"index";a:3:{s:3:"url";s:1:"/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:7:"archive";a:3:{s:3:"url";s:6:"/blog/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:2:"do";a:3:{s:3:"url";s:22:"/action/[action:alpha]";s:6:"widget";s:9:"Widget_Do";s:6:"action";s:6:"action";}s:4:"post";a:3:{s:3:"url";s:24:"/archives/[cid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:10:"attachment";a:3:{s:3:"url";s:26:"/attachment/[cid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:8:"category";a:3:{s:3:"url";s:17:"/category/[slug]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:3:"tag";a:3:{s:3:"url";s:12:"/tag/[slug]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:6:"author";a:3:{s:3:"url";s:22:"/author/[uid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:6:"search";a:3:{s:3:"url";s:19:"/search/[keywords]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:10:"index_page";a:3:{s:3:"url";s:21:"/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"archive_page";a:3:{s:3:"url";s:26:"/blog/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:13:"category_page";a:3:{s:3:"url";s:32:"/category/[slug]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:8:"tag_page";a:3:{s:3:"url";s:27:"/tag/[slug]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"author_page";a:3:{s:3:"url";s:37:"/author/[uid:digital]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"search_page";a:3:{s:3:"url";s:34:"/search/[keywords]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"archive_year";a:3:{s:3:"url";s:18:"/[year:digital:4]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:13:"archive_month";a:3:{s:3:"url";s:36:"/[year:digital:4]/[month:digital:2]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"archive_day";a:3:{s:3:"url";s:52:"/[year:digital:4]/[month:digital:2]/[day:digital:2]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:17:"archive_year_page";a:3:{s:3:"url";s:38:"/[year:digital:4]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:18:"archive_month_page";a:3:{s:3:"url";s:56:"/[year:digital:4]/[month:digital:2]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:16:"archive_day_page";a:3:{s:3:"url";s:72:"/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"comment_page";a:3:{s:3:"url";s:53:"[permalink:string]/comment-page-[commentPage:digital]";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:4:"feed";a:3:{s:3:"url";s:20:"/feed[feed:string:0]";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:4:"feed";}s:8:"feedback";a:3:{s:3:"url";s:31:"[permalink:string]/[type:alpha]";s:6:"widget";s:15:"Widget_Feedback";s:6:"action";s:6:"action";}s:4:"page";a:3:{s:3:"url";s:12:"/[slug].html";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}}',
'routingTable' => serialize(install_get_default_routers()),
'actionTable' => 'a:0:{}',
'panelTable' => 'a:0:{}',
'attachmentTypes' => '@image@',
@ -405,7 +566,7 @@ function install_redirect(string $url)
*/
function install_js_support()
{
$options = \Typecho\Widget::widget(\Widget\Options::class);
$options = \Widget\Options::alloc();
?>
<div id="success" class="row typecho-page-main hidden">
@ -991,7 +1152,7 @@ function install_step_2_perform()
*/
function install_step_3()
{
$options = \Typecho\Widget::widget(\Widget\Options::class);
$options = \Widget\Options::alloc();
?>
<div class="row typecho-page-main">
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
@ -1049,7 +1210,7 @@ function install_step_3_perform()
$request = \Typecho\Request::getInstance();
$defaultPassword = \Typecho\Common::randString(8);
$options = \Typecho\Widget::widget(\Widget\Options::class);
$options = \Widget\Options::alloc();
if (install_is_cli()) {
$config = [
@ -1189,7 +1350,7 @@ function install_step_3_perform()
install_success(0, [
$config['userName'],
$config['userPassword'],
\Typecho\Widget::widget(\Widget\Security::class)->getTokenUrl($loginUrl, $request->getReferer()),
\Widget\Security::alloc()->getTokenUrl($loginUrl, $request->getReferer()),
$options->siteUrl
]);
}
@ -1208,8 +1369,8 @@ function install_dispatch()
}
// init default options
$options = \Typecho\Widget::widget(\Widget\Options::class, install_get_default_options());
\Typecho\Widget::widget(\Widget\Init::class);
$options = \Widget\Options::alloc(install_get_default_options());
\Widget\Init::alloc();
// install finished yet
if (

View File

@ -78,8 +78,8 @@ namespace Typecho {
$path = str_replace(
['_', '\\'],
'/',
(defined('__TYPECHO_REWRITE_CLASS__') && isset(__TYPECHO_REWRITE_CLASS__[$className]))
? __TYPECHO_REWRITE_CLASS__[$className] : $className
(defined('__TYPECHO_CLASS_ALIASES__') && isset(__TYPECHO_CLASS_ALIASES__[$className]))
? __TYPECHO_CLASS_ALIASES__[$className] : $className
) . '.php';
$defaultFile = __TYPECHO_ROOT_DIR__ . '/var/' . $path;
@ -106,8 +106,8 @@ namespace Typecho {
&& !interface_exists($className, false)
&& !trait_exists($className, false)
) {
$aliasClass = (defined('__TYPECHO_REWRITE_CLASS__') && isset(__TYPECHO_REWRITE_CLASS__[$className]))
? __TYPECHO_REWRITE_CLASS__[$className] : '\\' . str_replace('_', '\\', $className);
$aliasClass = (defined('__TYPECHO_CLASS_ALIASES__') && isset(__TYPECHO_CLASS_ALIASES__[$className]))
? __TYPECHO_CLASS_ALIASES__[$className] : '\\' . str_replace('_', '\\', $className);
class_alias($aliasClass, $className);
}
});

View File

@ -148,6 +148,37 @@ abstract class Widget
return self::$widgetPool[$key];
}
/**
* alloc widget instance
*
* @param mixed $params
* @param mixed $request
* @param bool $enableResponse
* @return $this
*/
public static function alloc($params = null, $request = null, bool $enableResponse = true): Widget
{
return self::widget(static::class, $params, $request, $enableResponse);
}
/**
* alloc widget instance with alias
*
* @param string $alias
* @param mixed $params
* @param mixed $request
* @param bool $enableResponse
* @return $this
*/
public static function allocWithAlias(
string $alias,
$params = null,
$request = null,
bool $enableResponse = true
): Widget {
return self::widget(static::class . '@' . $alias, $params, $request, $enableResponse);
}
/**
* 释放组件
*
@ -162,10 +193,16 @@ abstract class Widget
/**
* 释放组件
*
* @param string $alias 组件名称
* @param string|null $alias 组件名称
*/
public static function destroy(string $alias)
public static function destroy(?string $alias = null)
{
if (!isset($alias)) {
$alias = static::class;
} elseif (Common::nativeClassName(static::class) != 'Typecho_Widget') {
$alias = static::class . '@' . $alias;
}
if (isset(self::$widgetPool[$alias])) {
unset(self::$widgetPool[$alias]);
}

View File

@ -58,7 +58,7 @@ class Action extends Widget
$action = $this->request->action;
/** 判断是否为plugin */
$actionTable = array_merge($this->map, unserialize(self::widget('Widget_Options')->actionTable));
$actionTable = array_merge($this->map, unserialize(Options::alloc()->actionTable));
if (isset($actionTable[$action])) {
$widgetName = $actionTable[$action];

View File

@ -18,6 +18,7 @@ use Widget\Base\Users;
use Widget\Comments\Ping;
use Widget\Comments\Recent;
use Widget\Contents\Attachment\Related;
use Widget\Contents\Related\Author;
use Widget\Metas\Category\Rows;
if (!defined('__TYPECHO_ROOT_DIR__')) {
@ -895,7 +896,7 @@ class Archive extends Contents
'allowComment' => $this->allow('comment')
];
return self::widget(\Widget\Comments\Archive::class, $parameter);
return \Widget\Comments\Archive::alloc($parameter);
}
/**
@ -905,7 +906,7 @@ class Archive extends Contents
*/
public function pings(): Ping
{
return self::widget(Ping::class, [
return Ping::alloc([
'parentId' => $this->hidden ? 0 : $this->cid,
'parentContent' => $this->row,
'allowPing' => $this->allow('ping')
@ -921,7 +922,7 @@ class Archive extends Contents
*/
public function attachments(int $limit = 0, int $offset = 0): Related
{
return self::widget(Related::class . '@' . $this->cid . '-' . uniqid(), [
return Related::allocWithAlias($this->cid . '-' . uniqid(), [
'parentId' => $this->cid,
'limit' => $limit,
'offset' => $offset
@ -1019,14 +1020,12 @@ class Archive extends Contents
switch ($type) {
case 'author':
/** 如果访问权限被设置为禁止,则tag会被置为空 */
return self::widget(
'\Widget\Contents\Related\Author',
return Author::alloc(
['cid' => $this->cid, 'type' => $this->type, 'author' => $this->author->uid, 'limit' => $limit]
);
default:
/** 如果访问权限被设置为禁止,则tag会被置为空 */
return self::widget(
'\Widget\Contents\Related',
return \Widget\Contents\Related::alloc(
['cid' => $this->cid, 'type' => $this->type, 'tags' => $this->tags, 'limit' => $limit]
);
}
@ -1429,9 +1428,9 @@ class Archive extends Contents
));
if ('comments' == $this->parameter->type) {
$comments = self::widget(Recent::class, 'pageSize=10');
$comments = Recent::alloc('pageSize=10');
} else {
$comments = self::widget(Recent::class, 'pageSize=10&parentId=' . $this->cid);
$comments = Recent::alloc('pageSize=10&parentId=' . $this->cid);
}
while ($comments->next()) {
@ -1864,7 +1863,7 @@ class Archive extends Contents
throw new WidgetException(_t('分类不存在'), 404);
}
$categoryListWidget = self::widget(Rows::class, 'current=' . $category['mid']);
$categoryListWidget = Rows::alloc('current=' . $category['mid']);
$category = $categoryListWidget->filter($category);
if (isset($directory) && ($this->request->directory != implode('/', $category['directory']))) {
@ -1938,7 +1937,7 @@ class Archive extends Contents
/** 如果是标签 */
$tag = $this->db->fetchRow(
$tagSelect,
[self::widget(Metas::class), 'filter']
[Metas::alloc(), 'filter']
);
if (!$tag) {
@ -1998,7 +1997,7 @@ class Archive extends Contents
$author = $this->db->fetchRow(
$this->db->select()->from('table.users')
->where('uid = ?', $uid),
[self::widget(Users::class), 'filter']
[User::alloc(), 'filter']
);
if (!$author) {

View File

@ -1,26 +1,31 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* Typecho Blog Platform
*
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
namespace Widget;
use Typecho\Common;
use Typecho\Cookie;
use Typecho\Exception;
use Typecho\Plugin;
use Widget\Base\Options as BaseOptions;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 备份工具
*
* @package Widget
*/
class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_Do
class Backup extends BaseOptions implements ActionInterface
{
const HEADER = '%TYPECHO_BACKUP_XXXX%';
const HEADER_VERSION = '0001';
public const HEADER = '%TYPECHO_BACKUP_XXXX%';
public const HEADER_VERSION = '0001';
/**
* @var array
*/
private $_types = [
private $types = [
'contents' => 1,
'comments' => 2,
'metas' => 3,
@ -32,7 +37,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
/**
* @var array
*/
private $_fields = [
private $fields = [
'contents' => [
'cid', 'title', 'slug', 'created', 'modified', 'text', 'order', 'authorId',
'template', 'type', 'status', 'password', 'commentsNum', 'allowComment', 'allowPing', 'allowFeed', 'parent'
@ -46,7 +51,8 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
],
'relationships' => ['cid', 'mid'],
'users' => [
'uid', 'name', 'password', 'mail', 'url', 'screenName', 'created', 'activated', 'logged', 'group', 'authCode'
'uid', 'name', 'password', 'mail', 'url', 'screenName',
'created', 'activated', 'logged', 'group', 'authCode'
],
'fields' => [
'cid', 'name', 'type', 'str_value', 'int_value', 'float_value'
@ -56,24 +62,24 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
/**
* @var array
*/
private $_lastIds = [];
private $lastIds = [];
/**
* @var array
*/
private $_cleared = [];
private $cleared = [];
/**
* @var bool
*/
private $_login = false;
private $login = false;
/**
* 列出已有备份文件
*
* @return array
*/
public function listFiles()
public function listFiles(): array
{
return array_map('basename', glob(__TYPECHO_BACKUP_DIR__ . '/*.dat'));
}
@ -92,6 +98,8 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
/**
* 导出数据
*
* @throws \Typecho\Db\Exception
*/
private function export()
{
@ -106,7 +114,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
fwrite($fp, $header);
$db = $this->db;
foreach ($this->_types as $type => $val) {
foreach ($this->types as $type => $val) {
$page = 1;
do {
$rows = $db->fetchAll($db->select()->from('table.' . $type)->page($page, 20));
@ -118,7 +126,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
} while (count($rows) == 20);
}
Typecho_Plugin::factory(__CLASS__)->export($fp);
Plugin::factory(__CLASS__)->export($fp);
fwrite($fp, $header);
fclose($fp);
@ -130,7 +138,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
* @param $data
* @return string
*/
private function buildBuffer($type, $data)
private function buildBuffer($type, $data): string
{
$body = '';
$schema = [];
@ -141,7 +149,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
}
$header = json_encode($schema);
return Typecho_Common::buildBackupBuffer($type, $header, $body);
return Common::buildBackupBuffer($type, $header, $body);
}
/**
@ -151,19 +159,19 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
* @param $data
* @return array
*/
private function applyFields($table, $data)
private function applyFields($table, $data): array
{
$result = [];
foreach ($data as $key => $val) {
$index = array_search($key, $this->_fields[$table]);
$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;
$this->lastIds[$table] = isset($this->lastIds[$table])
? max($this->lastIds[$table], $val) : $val;
}
}
}
@ -178,25 +186,25 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
{
$path = null;
if (!empty($_FILES)) {
$file = array_pop($_FILES);
if (!empty($FILES)) {
$file = array_pop($FILES);
if (0 == $file['error'] && is_uploaded_file($file['tmp_name'])) {
$path = $file['tmp_name'];
} else {
self::widget('Widget_Notice')->set(_t('备份文件上传失败'), 'error');
Notice::alloc()->set(_t('备份文件上传失败'), 'error');
$this->response->goBack();
}
} else {
if (!$this->request->is('file')) {
self::widget('Widget_Notice')->set(_t('没有选择任何备份文件'), 'error');
Notice::alloc()->set(_t('没有选择任何备份文件'), 'error');
$this->response->goBack();
}
$path = __TYPECHO_BACKUP_DIR__ . '/' . $this->request->get('file');
if (!file_exists($path)) {
self::widget('Widget_Notice')->set(_t('备份文件不存在'), 'error');
Notice::alloc()->set(_t('备份文件不存在'), 'error');
$this->response->goBack();
}
}
@ -208,13 +216,14 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
* 解析数据
*
* @param $file
* @throws \Typecho\Db\Exception
*/
private function extractData($file)
{
$fp = @fopen($file, 'rb');
if (!$fp) {
self::widget('Widget_Notice')->set(_t('无法读取备份文件'), 'error');
Notice::alloc()->set(_t('无法读取备份文件'), 'error');
$this->response->goBack();
}
@ -223,7 +232,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
if ($fileSize < $headerSize) {
@fclose($fp);
self::widget('Widget_Notice')->set(_t('备份文件格式错误'), 'error');
Notice::alloc()->set(_t('备份文件格式错误'), 'error');
$this->response->goBack();
}
@ -231,7 +240,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
if (!$this->parseHeader($fileHeader, $version)) {
@fclose($fp);
self::widget('Widget_Notice')->set(_t('备份文件格式错误'), 'error');
Notice::alloc()->set(_t('备份文件格式错误'), 'error');
$this->response->goBack();
}
@ -240,7 +249,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
if (!$this->parseHeader($fileFooter, $version)) {
@fclose($fp);
self::widget('Widget_Notice')->set(_t('备份文件格式错误'), 'error');
Notice::alloc()->set(_t('备份文件格式错误'), 'error');
$this->response->goBack();
}
@ -248,11 +257,11 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
$offset = $headerSize;
while (!feof($fp) && $offset + $headerSize < $fileSize) {
$data = Typecho_Common::extractBackupBuffer($fp, $offset, $version);
$data = Common::extractBackupBuffer($fp, $offset, $version);
if (!$data) {
@fclose($fp);
self::widget('Widget_Notice')->set(_t('恢复数据出现错误'), 'error');
Notice::alloc()->set(_t('恢复数据出现错误'), 'error');
$this->response->goBack();
}
@ -262,14 +271,14 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
// 针对PGSQL重置计数
if (false !== strpos($this->db->getVersion(), 'pgsql')) {
foreach ($this->_lastIds as $table => $id) {
foreach ($this->lastIds as $table => $id) {
$seq = $this->db->getPrefix() . $table . '_seq';
$this->db->query('ALTER SEQUENCE ' . $seq . ' RESTART WITH ' . ($id + 1));
}
}
@fclose($fp);
self::widget('Widget_Notice')->set(_t('数据恢复完成'), 'success');
Notice::alloc()->set(_t('数据恢复完成'), 'success');
$this->response->goBack();
}
@ -278,7 +287,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
* @param $version
* @return bool
*/
private function parseHeader($str, &$version)
private function parseHeader($str, &$version): bool
{
if (!$str || strlen($str) != strlen(self::HEADER)) {
return false;
@ -299,7 +308,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
*/
private function processData($type, $header, $body)
{
$table = array_search($type, $this->_types);
$table = array_search($type, $this->types);
if (!empty($table)) {
$schema = json_decode($header, true);
@ -313,7 +322,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
$this->importData($table, $data);
} else {
Typecho_Plugin::factory(__CLASS__)->import($type, $header, $body);
Plugin::factory(__CLASS__)->import($type, $header, $body);
}
}
@ -322,27 +331,26 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
*
* @param $table
* @param $data
* @throws Typecho_Exception
*/
private function importData($table, $data)
{
$db = $this->db;
try {
if (empty($this->_cleared[$table])) {
if (empty($this->cleared[$table])) {
// 清除数据
$db->truncate('table.' . $table);
$this->_cleared[$table] = true;
$this->cleared[$table] = true;
}
if (!$this->_login && 'users' == $table && $data['group'] == 'administrator') {
if (!$this->login && 'users' == $table && $data['group'] == 'administrator') {
// 重新登录
$this->reLogin($data);
}
$db->query($db->insert('table.' . $table)->rows($this->applyFields($table, $data)));
} catch (Exception $e) {
self::widget('Widget_Notice')->set(_t('恢复过程中遇到如下错误: %s', $e->getMessage()), 'error');
Notice::alloc()->set(_t('恢复过程中遇到如下错误: %s', $e->getMessage()), 'error');
$this->response->goBack();
}
}
@ -357,14 +365,14 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
{
if (empty($user['authCode'])) {
$user['authCode'] = function_exists('openssl_random_pseudo_bytes') ?
bin2hex(openssl_random_pseudo_bytes(16)) : sha1(Typecho_Common::randString(20));
bin2hex(openssl_random_pseudo_bytes(16)) : sha1(Common::randString(20));
}
$user['activated'] = $this->options->time;
$user['logged'] = $user['activated'];
Typecho_Cookie::set('__typecho_uid', $user['uid']);
Typecho_Cookie::set('__typecho_authCode', Typecho_Common::hash($user['authCode']));
$this->_login = true;
Cookie::set('__typecho_uid', $user['uid']);
Cookie::set('__typecho_authCode', Common::hash($user['authCode']));
$this->login = true;
}
}

View File

@ -65,9 +65,9 @@ abstract class Base extends Widget
$this->db = Db::get();
/** 初始化常用组件 */
$this->options = self::widget('Widget_Options');
$this->user = self::widget('Widget_User');
$this->security = self::widget('Widget_Security');
$this->options = Options::alloc();
$this->user = User::alloc();
$this->security = Security::alloc();
}
/**

View File

@ -286,9 +286,9 @@ class Comments extends Base
*/
protected function ___parentContent(): ?array
{
return $this->db->fetchRow(self::widget(Contents::class)->select()
return $this->db->fetchRow(Contents::alloc()->select()
->where('table.contents.cid = ?', $this->cid)
->limit(1), [self::widget(Contents::class), 'filter']);
->limit(1), [Contents::alloc(), 'filter']);
}
/**

View File

@ -447,7 +447,7 @@ class Contents extends Base
->select()->from('table.metas')
->join('table.relationships', 'table.relationships.mid = table.metas.mid')
->where('table.relationships.cid = ?', $value['cid'])
->where('table.metas.type = ?', 'category'), [self::widget(Rows::class), 'filter']);
->where('table.metas.type = ?', 'category'), [Rows::alloc(), 'filter']);
$value['category'] = null;
$value['directory'] = [];
@ -466,7 +466,7 @@ class Contents extends Base
$value['category'] = $value['categories'][0]['slug'];
$value['directory'] = self::widget(Rows::class)
$value['directory'] = Rows::alloc()
->getAllParentsSlug($value['categories'][0]['mid']);
$value['directory'][] = $value['category'];
}
@ -700,7 +700,7 @@ class Contents extends Base
public function directory(string $split = '/', bool $link = true, ?string $default = null)
{
$category = $this->categories[0];
$directory = self::widget(Rows::class)->getAllParents($category['mid']);
$directory = Rows::alloc()->getAllParents($category['mid']);
$directory[] = $category;
if ($directory) {
@ -762,7 +762,7 @@ class Contents extends Base
->select()->from('table.metas')
->join('table.relationships', 'table.relationships.mid = table.metas.mid')
->where('table.relationships.cid = ?', $this->cid)
->where('table.metas.type = ?', 'tag'), [self::widget(Metas::class), 'filter']);
->where('table.metas.type = ?', 'tag'), [Metas::alloc(), 'filter']);
}
/**
@ -772,7 +772,7 @@ class Contents extends Base
*/
protected function ___author(): Widget
{
return self::widget(Author::class . '@' . $this->cid, ['uid' => $this->authorId]);
return Author::allocWithAlias($this->cid, ['uid' => $this->authorId]);
}
/**

View File

@ -148,8 +148,8 @@ class Admin extends Comments
protected function ___parentContent(): ?array
{
$cid = isset($this->request->cid) ? $this->request->filter('int')->cid : $this->cid;
return $this->db->fetchRow(self::widget(Contents::class)->select()
return $this->db->fetchRow(Contents::alloc()->select()
->where('table.contents.cid = ?', $cid)
->limit(1), [self::widget(Contents::class), 'filter']);
->limit(1), [Contents::alloc(), 'filter']);
}
}

View File

@ -37,7 +37,7 @@ class Edit extends Comments implements ActionInterface
}
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$updateRows > 0 ? _t('评论已经被标记为待审核') : _t('没有评论被标记为待审核'),
$updateRows > 0 ? 'success' : 'notice'
@ -106,7 +106,7 @@ class Edit extends Comments implements ActionInterface
}
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$updateRows > 0 ? _t('评论已经被标记为垃圾') : _t('没有评论被标记为垃圾'),
$updateRows > 0 ? 'success' : 'notice'
@ -133,7 +133,7 @@ class Edit extends Comments implements ActionInterface
}
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$updateRows > 0 ? _t('评论已经被通过') : _t('没有评论被通过'),
$updateRows > 0 ? 'success' : 'notice'
@ -190,7 +190,7 @@ class Edit extends Comments implements ActionInterface
} else {
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$deleteRows > 0 ? _t('评论已经被删除') : _t('没有评论被删除'),
$deleteRows > 0 ? 'success' : 'notice'
@ -220,7 +220,7 @@ class Edit extends Comments implements ActionInterface
$deleteRows = $this->db->query($deleteQuery);
/** 设置提示信息 */
self::widget(Notice::class)->set(
Notice::alloc()->set(
$deleteRows > 0 ? _t('所有垃圾评论已经被删除') : _t('没有垃圾评论被删除'),
$deleteRows > 0 ? 'success' : 'notice'
);

View File

@ -265,7 +265,7 @@ class Edit extends PostEdit implements ActionInterface
: ['code' => 500, 'message' => _t('没有文件被删除')]);
} else {
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$deleteCount > 0 ? _t('文件已经被删除') : _t('没有文件被删除'),
$deleteCount > 0 ? 'success' : 'notice'

View File

@ -100,16 +100,16 @@ class Edit extends PostEdit implements ActionInterface
$this->pluginHandle()->finishPublish($contents, $this);
/** 发送ping */
self::widget(Service::class)->sendPing($this->cid);
Service::alloc()->sendPing($this->cid);
/** 设置提示信息 */
self::widget(Notice::class)->set(
Notice::alloc()->set(
_t('页面 "<a href="%s">%s</a>" 已经发布', $this->permalink, $this->title),
'success'
);
/** 设置高亮 */
self::widget(Notice::class)->highlight($this->theId);
Notice::alloc()->highlight($this->theId);
/** 页面跳转 */
$this->response->redirect(Common::url('manage-pages.php?', $this->options->adminUrl));
@ -122,7 +122,7 @@ class Edit extends PostEdit implements ActionInterface
$this->pluginHandle()->finishSave($contents, $this);
/** 设置高亮 */
self::widget(Notice::class)->highlight($this->cid);
Notice::alloc()->highlight($this->cid);
if ($this->request->isAjax()) {
$created = new Date($this->options->time);
@ -134,7 +134,7 @@ class Edit extends PostEdit implements ActionInterface
]);
} else {
/** 设置提示信息 */
self::widget(Notice::class)->set(_t('草稿 "%s" 已经被保存', $this->title), 'success');
Notice::alloc()->set(_t('草稿 "%s" 已经被保存', $this->title), 'success');
/** 返回原页面 */
$this->response->redirect(Common::url('write-page.php?cid=' . $this->cid, $this->options->adminUrl));
@ -189,7 +189,7 @@ class Edit extends PostEdit implements ActionInterface
}
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$markCount > 0 ? _t('页面已经被标记为<strong>%s</strong>', $statusList[$status]) : _t('没有页面被标记'),
$markCount > 0 ? 'success' : 'notice'
@ -250,7 +250,7 @@ class Edit extends PostEdit implements ActionInterface
}
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$deleteCount > 0 ? _t('页面已经被删除') : _t('没有页面被删除'),
$deleteCount > 0 ? 'success' : 'notice'
@ -285,7 +285,7 @@ class Edit extends PostEdit implements ActionInterface
}
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$deleteCount > 0 ? _t('草稿已经被删除') : _t('没有草稿被删除'),
$deleteCount > 0 ? 'success' : 'notice'

View File

@ -3,6 +3,7 @@
namespace Widget\Contents\Post;
use Typecho\Cookie;
use Typecho\Db;
use Typecho\Db\Exception as DbException;
use Typecho\Widget\Exception;
use Typecho\Db\Query;

View File

@ -51,7 +51,7 @@ class Date extends Widget
$this->db = Db::get();
/** 初始化常用组件 */
$this->options = self::widget('\Widget\Options');
$this->options = Options::alloc();
}
/**

View File

@ -105,7 +105,7 @@ class Edit extends Contents implements ActionInterface
public function filter(array $value): array
{
if ('post' == $value['type'] || 'page' == $value['type']) {
$draft = $this->db->fetchRow(self::widget(Contents::class)->select()
$draft = $this->db->fetchRow(Contents::alloc()->select()
->where(
'table.contents.parent = ? AND table.contents.type = ?',
$value['cid'],
@ -123,7 +123,7 @@ class Edit extends Contents implements ActionInterface
->select()->from('table.metas')
->join('table.relationships', 'table.relationships.mid = table.metas.mid')
->where('table.relationships.cid = ?', $draft['cid'])
->where('table.metas.type = ?', 'tag'), [self::widget(Metas::class), 'filter']);
->where('table.metas.type = ?', 'tag'), [Metas::alloc(), 'filter']);
$draft['cid'] = $value['cid'];
return $draft;
@ -293,15 +293,15 @@ class Edit extends Contents implements ActionInterface
/** 发送ping */
$trackback = array_unique(preg_split("/(\r|\n|\r\n)/", trim($this->request->trackback)));
self::widget(Service::class)->sendPing($this->cid, $trackback);
Service::alloc()->sendPing($this->cid, $trackback);
/** 设置提示信息 */
self::widget(Notice::class)->set('post' == $this->type ?
Notice::alloc()->set('post' == $this->type ?
_t('文章 "<a href="%s">%s</a>" 已经发布', $this->permalink, $this->title) :
_t('文章 "%s" 等待审核', $this->title), 'success');
/** 设置高亮 */
self::widget(Notice::class)->highlight($this->theId);
Notice::alloc()->highlight($this->theId);
/** 获取页面偏移 */
$pageQuery = $this->getPageOffsetQuery($this->cid);
@ -317,7 +317,7 @@ class Edit extends Contents implements ActionInterface
$this->pluginHandle()->finishSave($contents, $this);
/** 设置高亮 */
self::widget(Notice::class)->highlight($this->cid);
Notice::alloc()->highlight($this->cid);
if ($this->request->isAjax()) {
$created = new TypechoDate();
@ -329,7 +329,7 @@ class Edit extends Contents implements ActionInterface
]);
} else {
/** 设置提示信息 */
self::widget(Notice::class)->set(_t('草稿 "%s" 已经被保存', $this->title), 'success');
Notice::alloc()->set(_t('草稿 "%s" 已经被保存', $this->title), 'success');
/** 返回原页面 */
$this->response->redirect(Common::url('write-post.php?cid=' . $this->cid, $this->options->adminUrl));
@ -595,7 +595,7 @@ class Edit extends Contents implements ActionInterface
}
/** 取出插入tag */
$insertTags = self::widget(Metas::class)->scanTags($tags);
$insertTags = Metas::alloc()->scanTags($tags);
/** 插入tag */
if ($insertTags) {
@ -845,7 +845,7 @@ class Edit extends Contents implements ActionInterface
}
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$markCount > 0 ? _t('文章已经被标记为<strong>%s</strong>', $statusList[$status]) : _t('没有文章被标记'),
$markCount > 0 ? 'success' : 'notice'
@ -915,11 +915,11 @@ class Edit extends Contents implements ActionInterface
// 清理标签
if ($deleteCount > 0) {
self::widget(Metas::class)->clearTags();
Metas::alloc()->clearTags();
}
/** 设置提示信息 */
self::widget(Notice::class)->set(
Notice::alloc()->set(
$deleteCount > 0 ? _t('文章已经被删除') : _t('没有文章被删除'),
$deleteCount > 0 ? 'success' : 'notice'
);
@ -965,7 +965,7 @@ class Edit extends Contents implements ActionInterface
}
/** 设置提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(
$deleteCount > 0 ? _t('草稿已经被删除') : _t('没有草稿被删除'),
$deleteCount > 0 ? 'success' : 'notice'
@ -1002,7 +1002,7 @@ class Edit extends Contents implements ActionInterface
->select()->from('table.metas')
->join('table.relationships', 'table.relationships.mid = table.metas.mid')
->where('table.relationships.cid = ?', $this->cid)
->where('table.metas.type = ?', 'tag'), [self::widget(Metas::class), 'filter']);
->where('table.metas.type = ?', 'tag'), [Metas::alloc(), 'filter']);
}
return [];
@ -1030,14 +1030,14 @@ class Edit extends Contents implements ActionInterface
if ('post_draft' == $this->type) {
return $this->row;
} else {
return $this->db->fetchRow(self::widget(Contents::class)->select()
return $this->db->fetchRow(Contents::alloc()->select()
->where(
'table.contents.parent = ? AND (table.contents.type = ? OR table.contents.type = ?)',
$this->cid,
'post_draft',
'page_draft'
)
->limit(1), [self::widget(Contents::class), 'filter']);
->limit(1), [Contents::alloc(), 'filter']);
}
}

View File

@ -33,7 +33,7 @@ class Init extends Widget
public function execute()
{
// init class
define('__TYPECHO_REWRITE_CLASS__', [
define('__TYPECHO_CLASS_ALIASES__', [
'Typecho_Plugin_Interface' => '\Typecho\Plugin\PluginInterface',
'Typecho_Widget_Helper_Empty' => '\Typecho\Widget\Helper\EmptyClass',
'Widget_Abstract' => '\Widget\Base',
@ -44,12 +44,14 @@ class Init extends Widget
'Widget_Abstract_Users' => '\Widget\Base\Users',
'Widget_Metas_Category_List' => '\Widget\Metas\Category\Rows',
'Widget_Contents_Page_List' => '\Widget\Contents\Page\Rows',
'Widget_Plugins_List' => '\Widget\Plugins\Rows',
'Widget_Themes_List' => '\Widget\Themes\Rows',
'Widget_Interface_Do' => '\Widget\ActionInterface',
'Widget_Do' => '\Widget\Action',
]);
/** 对变量赋值 */
$options = self::widget(Options::class);
$options = Options::alloc();
/** 检查安装状态 */
if (!defined('__TYPECHO_INSTALL__') && !$options->installed) {
@ -105,7 +107,7 @@ class Init extends Widget
Date::setTimezoneOffset($options->timezone);
/** 开始会话, 减小负载只针对后台打开session支持 */
if (!defined('__TYPECHO_INSTALL__') && self::widget(User::class)->hasLogin()) {
if (!defined('__TYPECHO_INSTALL__') && User::alloc()->hasLogin()) {
@session_start();
}
}

View File

@ -1,14 +1,14 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 登录动作
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget;
use Typecho\Cookie;
use Typecho\Validate;
use Widget\Base\Users;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 登录组件
@ -18,7 +18,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Login extends Widget_Abstract_Users implements Widget_Interface_Do
class Login extends Users implements ActionInterface
{
/**
* 初始化函数
@ -38,44 +38,58 @@ class Widget_Login extends Widget_Abstract_Users implements Widget_Interface_Do
}
/** 初始化验证类 */
$validator = new Typecho_Validate();
$validator = new Validate();
$validator->addRule('name', 'required', _t('请输入用户名'));
$validator->addRule('password', 'required', _t('请输入密码'));
/** 截获验证异常 */
if ($error = $validator->run($this->request->from('name', 'password'))) {
Typecho_Cookie::set('__typecho_remember_name', $this->request->name);
Cookie::set('__typecho_remember_name', $this->request->name);
/** 设置提示信息 */
self::widget('Widget_Notice')->set($error);
Notice::alloc()->set($error);
$this->response->goBack();
}
/** 开始验证用户 **/
$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);
$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
);
/** 比对密码 */
if (!$valid) {
/** 防止穷举,休眠3秒 */
sleep(3);
$this->pluginHandle()->loginFail($this->user, $this->request->name,
$this->request->password, 1 == $this->request->remember);
$this->pluginHandle()->loginFail(
$this->user,
$this->request->name,
$this->request->password,
1 == $this->request->remember
);
Typecho_Cookie::set('__typecho_remember_name', $this->request->name);
self::widget('Widget_Notice')->set(_t('用户名或密码无效'), 'error');
Cookie::set('__typecho_remember_name', $this->request->name);
Notice::alloc()->set(_t('用户名或密码无效'), 'error');
$this->response->goBack('?referer=' . urlencode($this->request->referer));
}
$this->pluginHandle()->loginSucceed($this->user, $this->request->name,
$this->request->password, 1 == $this->request->remember);
$this->pluginHandle()->loginSucceed(
$this->user,
$this->request->name,
$this->request->password,
1 == $this->request->remember
);
/** 跳转验证后地址 */
if (!empty($this->request->referer)) {
/** fix #952 & validate redirect url */
if (0 === strpos($this->request->referer, $this->options->adminUrl)
|| 0 === strpos($this->request->referer, $this->options->siteUrl)) {
if (
0 === strpos($this->request->referer, $this->options->adminUrl)
|| 0 === strpos($this->request->referer, $this->options->siteUrl)
) {
$this->response->redirect($this->request->referer);
}
} elseif (!$this->user->pass('contributor', true)) {

View File

@ -1,14 +1,12 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 登出动作
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget;
use Widget\Base\Users;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 登出组件
@ -18,7 +16,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Logout extends Widget_Abstract_Users implements Widget_Interface_Do
class Logout extends Users implements ActionInterface
{
/**
* 初始化函数
@ -33,7 +31,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);
@session_destroy();
$this->response->goBack(null, $this->options->index);
}
}

View File

@ -1,19 +1,31 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* Typecho Blog Platform
*
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget;
use Typecho\Common;
use Typecho\Widget;
use Widget\Plugins\Config;
use Widget\Themes\Files;
use Widget\Users\Edit as UsersEdit;
use Widget\Contents\Attachment\Edit as AttachmentEdit;
use Widget\Contents\Post\Edit as PostEdit;
use Widget\Contents\Page\Edit as PageEdit;
use Widget\Contents\Post\Admin as PostAdmin;
use Widget\Comments\Admin as CommentsAdmin;
use Widget\Metas\Category\Admin as CategoryAdmin;
use Widget\Metas\Category\Edit as CategoryEdit;
use Widget\Metas\Tag\Admin as TagAdmin;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 后台菜单显示
*
* @package Widget
*/
class Widget_Menu extends Typecho_Widget
class Menu extends Widget
{
/**
* 当前菜单标题
@ -30,50 +42,44 @@ class Widget_Menu extends Typecho_Widget
/**
* 全局选项
*
* @access protected
* @var Widget_Options
* @var Options
*/
protected $options;
/**
* 用户对象
*
* @access protected
* @var Widget_User
* @var User
*/
protected $user;
/**
* 父菜单列表
*
* @access private
* @var array
*/
private $_menu = [];
private $menu = [];
/**
* 当前父菜单
*
* @access private
* @var integer
*/
private $_currentParent = 1;
private $currentParent = 1;
/**
* 当前子菜单
*
* @access private
* @var integer
*/
private $_currentChild = 0;
private $currentChild = 0;
/**
* 当前页面
*
* @access private
* @var string
*/
private $_currentUrl;
private $currentUrl;
/**
* 构造函数,初始化组件
@ -89,15 +95,12 @@ class Widget_Menu extends Typecho_Widget
parent::__construct($request, $response, $params);
/** 初始化常用组件 */
$this->options = self::widget('Widget_Options');
$this->user = self::widget('Widget_User');
$this->options = Options::alloc();
$this->user = User::alloc();
}
/**
* 执行函数,初始化菜单
*
* @access public
* @return void
*/
public function execute()
{
@ -112,9 +115,9 @@ class Widget_Menu extends Typecho_Widget
[_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],
[[Config::class, 'getMenuTitle'], [Config::class, '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],
[[Files::class, 'getMenuTitle'], [Files::class, 'getMenuTitle'], 'theme-editor.php', 'administrator', true],
[_t('设置外观'), _t('设置外观'), 'options-theme.php', 'administrator', true],
[_t('备份'), _t('备份'), 'backup.php', 'administrator'],
[_t('升级'), _t('升级程序'), 'upgrade.php', 'administrator', true],
@ -122,28 +125,28 @@ class Widget_Menu extends Typecho_Widget
],
[
[_t('撰写文章'), _t('撰写新文章'), 'write-post.php', 'contributor'],
[['Widget_Contents_Post_Edit', 'getMenuTitle'], ['Widget_Contents_Post_Edit', 'getMenuTitle'], 'write-post.php?cid=', 'contributor', true],
[[PostEdit::class, 'getMenuTitle'], [PostEdit::class, '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],
[[PageEdit::class, 'getMenuTitle'], [PageEdit::class, '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],
[[PostAdmin::class, 'getMenuTitle'], [PostAdmin::class, '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],
[[CommentsAdmin::class, 'getMenuTitle'], [CommentsAdmin::class, '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],
[[CategoryAdmin::class, 'getMenuTitle'], [CategoryAdmin::class, 'getMenuTitle'], 'manage-categories.php?parent=', 'editor', true, ['Widget_Metas_Category_Admin', 'getAddLink']],
[[CategoryEdit::class, 'getMenuTitle'], [CategoryEdit::class, 'getMenuTitle'], 'category.php?mid=', 'editor', true],
[[CategoryEdit::class, 'getMenuTitle'], [CategoryEdit::class, '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],
[[TagAdmin::class, 'getMenuTitle'], [TagAdmin::class, '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],
[[AttachmentEdit::class, 'getMenuTitle'], [AttachmentEdit::class, '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],
[[UsersEdit::class, 'getMenuTitle'], [UsersEdit::class, 'getMenuTitle'], 'user.php?uid=', 'administrator', true],
],
[
[_t('基本'), _t('基本设置'), 'options-general.php', 'administrator'],
@ -198,7 +201,7 @@ class Widget_Menu extends Typecho_Widget
$orgHidden = $hidden;
// parse url
$url = Typecho_Common::url($url, $adminUrl);
$url = Common::url($url, $adminUrl);
// compare url
$urlParts = parse_url($url);
@ -219,10 +222,12 @@ class Widget_Menu extends Typecho_Widget
}
}
if ($validate
if (
$validate
&& basename($urlParts['path']) == 'extending.php'
&& !empty($currentUrlParams['panel']) && !empty($urlParams['panel'])
&& $urlParams['panel'] != $currentUrlParams['panel']) {
&& $urlParams['panel'] != $currentUrlParams['panel']
) {
$validate = false;
}
@ -235,7 +240,7 @@ class Widget_Menu extends Typecho_Widget
}
if (!$hidden) {
$showedChildrenCount ++;
$showedChildrenCount++;
if (empty($firstUrl)) {
$firstUrl = $url;
@ -243,17 +248,17 @@ class Widget_Menu extends Typecho_Widget
if (is_array($name)) {
[$widget, $method] = $name;
$name = Typecho_Widget::widget($widget)->$method();
$name = self::widget($widget)->$method();
}
if (is_array($title)) {
[$widget, $method] = $title;
$title = Typecho_Widget::widget($widget)->$method();
$title = self::widget($widget)->$method();
}
if (is_array($addLink)) {
[$widget, $method] = $addLink;
$addLink = Typecho_Widget::widget($widget)->$method();
$addLink = self::widget($widget)->$method();
}
}
@ -262,10 +267,10 @@ class Widget_Menu extends Typecho_Widget
$this->user->pass($access);
}
$this->_currentParent = $key;
$this->_currentChild = $inKey;
$this->currentParent = $key;
$this->currentChild = $inKey;
$this->title = $title;
$this->addLink = $addLink ? Typecho_Common::url($addLink, $adminUrl) : null;
$this->addLink = $addLink ? Common::url($addLink, $adminUrl) : null;
}
$children[$inKey] = [
@ -282,35 +287,31 @@ class Widget_Menu extends Typecho_Widget
$menu[$key] = [$parentNode, $showedChildrenCount > 0, $firstUrl, $children];
}
$this->_menu = $menu;
$this->_currentUrl = $currentUrl;
$this->menu = $menu;
$this->currentUrl = $currentUrl;
}
/**
* 获取当前菜单
*
* @access public
* @return array
*/
public function getCurrentMenu()
public function getCurrentMenu(): ?array
{
return $this->_currentParent > 0 ? $this->_menu[$this->_currentParent][3][$this->_currentChild] : null;
return $this->currentParent > 0 ? $this->menu[$this->currentParent][3][$this->currentChild] : null;
}
/**
* 输出父级菜单
*
* @access public
* @return string
*/
public function output($class = 'focus', $childClass = 'focus')
{
foreach ($this->_menu as $key => $node) {
foreach ($this->menu as $key => $node) {
if (!$node[1] || !$key) {
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\">";
@ -327,7 +328,7 @@ class Widget_Menu extends Typecho_Widget
}
$classes = [];
if ($key == $this->_currentParent && $inKey == $this->_currentChild) {
if ($key == $this->currentParent && $inKey == $this->currentChild) {
$classes[] = $childClass;
} elseif ($inNode[6]) {
continue;
@ -337,8 +338,9 @@ class Widget_Menu extends Typecho_Widget
$classes[] = 'last';
}
echo "<li" . (!empty($classes) ? ' class="' . implode(' ', $classes) . '"' : null) .
"><a href=\"" . ($key == $this->_currentParent && $inKey == $this->_currentChild ? $this->_currentUrl : $inNode[2]) . "\">{$inNode[0]}</a></li>";
echo "<li" . (!empty($classes) ? ' class="' . implode(' ', $classes) . '"' : null) . "><a href=\""
. ($key == $this->currentParent && $inKey == $this->currentChild ? $this->currentUrl : $inNode[2])
. "\">{$inNode[0]}</a></li>";
}
echo "</ul></ul>";

View File

@ -137,10 +137,10 @@ class Edit extends Metas implements ActionInterface
$this->push($category);
/** 设置高亮 */
self::widget(Notice::class)->highlight($this->theId);
Notice::alloc()->highlight($this->theId);
/** 提示信息 */
self::widget(Notice::class)->set(
Notice::alloc()->set(
_t('分类 <a href="%s">%s</a> 已经被增加', $this->permalink, $this->name),
'success'
);
@ -178,8 +178,8 @@ class Edit extends Metas implements ActionInterface
/** 父级分类 */
$options = [0 => _t('不选择')];
$parents = self::widget(
Rows::class . '@options',
$parents = Rows::allocWithAlias(
'options',
(isset($this->request->mid) ? 'ignore=' . $this->request->mid : '')
);
@ -302,10 +302,10 @@ class Edit extends Metas implements ActionInterface
$this->push($category);
/** 设置高亮 */
self::widget(Notice::class)->highlight($this->theId);
Notice::alloc()->highlight($this->theId);
/** 提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set(_t('分类 <a href="%s">%s</a> 已经被更新', $this->permalink, $this->name), 'success');
/** 转向原页 */
@ -336,7 +336,7 @@ class Edit extends Metas implements ActionInterface
}
/** 提示信息 */
self::widget(Notice::class)
Notice::alloc()
->set($deleteCount > 0 ? _t('分类已经删除') : _t('没有分类被删除'), $deleteCount > 0 ? 'success' : 'notice');
/** 转向原页 */
@ -354,7 +354,7 @@ class Edit extends Metas implements ActionInterface
$validator->addRule('merge', [$this, 'categoryExists'], _t('请选择需要合并的分类'));
if ($error = $validator->run($this->request->from('merge'))) {
self::widget(Notice::class)->set($error, 'error');
Notice::alloc()->set($error, 'error');
$this->response->goBack();
}
@ -365,9 +365,9 @@ class Edit extends Metas implements ActionInterface
$this->merge($merge, 'category', $categories);
/** 提示信息 */
self::widget(Notice::class)->set(_t('分类已经合并'), 'success');
Notice::alloc()->set(_t('分类已经合并'), 'success');
} else {
self::widget(Notice::class)->set(_t('没有选择任何分类'), 'notice');
Notice::alloc()->set(_t('没有选择任何分类'), 'notice');
}
/** 转向原页 */
@ -405,9 +405,9 @@ class Edit extends Metas implements ActionInterface
$this->refreshCountByTypeAndStatus($category, 'post', 'publish');
}
self::widget(Notice::class)->set(_t('分类刷新已经完成'), 'success');
Notice::alloc()->set(_t('分类刷新已经完成'), 'success');
} else {
self::widget(Notice::class)->set(_t('没有选择任何分类'), 'notice');
Notice::alloc()->set(_t('没有选择任何分类'), 'notice');
}
/** 转向原页 */
@ -427,7 +427,7 @@ class Edit extends Metas implements ActionInterface
$validator->addRule('mid', [$this, 'categoryExists'], _t('分类不存在'));
if ($error = $validator->run($this->request->from('mid'))) {
self::widget(Notice::class)->set($error, 'error');
Notice::alloc()->set($error, 'error');
} else {
$this->db->query($this->db->update('table.options')
->rows(['value' => $this->request->mid])
@ -437,10 +437,10 @@ class Edit extends Metas implements ActionInterface
->where('type = ?', 'category')->limit(1), [$this, 'push']);
/** 设置高亮 */
self::widget(Notice::class)->highlight($this->theId);
Notice::alloc()->highlight($this->theId);
/** 提示信息 */
self::widget(Notice::class)->set(
Notice::alloc()->set(
_t('<a href="%s">%s</a> 已经被设为默认分类', $this->permalink, $this->name),
'success'
);

View File

@ -135,10 +135,10 @@ class Edit extends Metas implements ActionInterface
$this->push($tag);
/** 设置高亮 */
self::widget(Notice::class)->highlight($this->theId);
Notice::alloc()->highlight($this->theId);
/** 提示信息 */
self::widget(Notice::class)->set(
Notice::alloc()->set(
_t('标签 <a href="%s">%s</a> 已经被增加', $this->permalink, $this->name),
'success'
);
@ -257,10 +257,10 @@ class Edit extends Metas implements ActionInterface
$this->push($tag);
/** 设置高亮 */
self::widget(Notice::class)->highlight($this->theId);
Notice::alloc()->highlight($this->theId);
/** 提示信息 */
self::widget(Notice::class)->set(
Notice::alloc()->set(
_t('标签 <a href="%s">%s</a> 已经被更新', $this->permalink, $this->name),
'success'
);
@ -289,7 +289,7 @@ class Edit extends Metas implements ActionInterface
}
/** 提示信息 */
self::widget(Notice::class)->set(
Notice::alloc()->set(
$deleteCount > 0 ? _t('标签已经删除') : _t('没有标签被删除'),
$deleteCount > 0 ? 'success' : 'notice'
);
@ -306,13 +306,13 @@ class Edit extends Metas implements ActionInterface
public function mergeTag()
{
if (empty($this->request->merge)) {
self::widget(Notice::class)->set(_t('请填写需要合并到的标签'), 'notice');
Notice::alloc()->set(_t('请填写需要合并到的标签'), 'notice');
$this->response->goBack();
}
$merge = $this->scanTags($this->request->merge);
if (empty($merge)) {
self::widget(Notice::class)->set(_t('合并到的标签名不合法'), 'error');
Notice::alloc()->set(_t('合并到的标签名不合法'), 'error');
$this->response->goBack();
}
@ -322,9 +322,9 @@ class Edit extends Metas implements ActionInterface
$this->merge($merge, 'tag', $tags);
/** 提示信息 */
self::widget(Notice::class)->set(_t('标签已经合并'), 'success');
Notice::alloc()->set(_t('标签已经合并'), 'success');
} else {
self::widget(Notice::class)->set(_t('没有选择任何标签'), 'notice');
Notice::alloc()->set(_t('没有选择任何标签'), 'notice');
}
/** 转向原页 */
@ -349,9 +349,9 @@ class Edit extends Metas implements ActionInterface
// 自动清理标签
$this->clearTags();
self::widget(Notice::class)->set(_t('标签刷新已经完成'), 'success');
Notice::alloc()->set(_t('标签刷新已经完成'), 'success');
} else {
self::widget(Notice::class)->set(_t('没有选择任何标签'), 'notice');
Notice::alloc()->set(_t('没有选择任何标签'), 'notice');
}
/** 转向原页 */

View File

@ -34,7 +34,7 @@ class Notice extends Widget
Cookie::set(
'__typecho_notice_highlight',
$theId,
self::widget(Options::class)->time + self::widget(Options::class)->timezone + 86400
Options::alloc()->time + Options::alloc()->timezone + 86400
);
}
@ -65,12 +65,12 @@ class Notice extends Widget
Cookie::set(
'__typecho_notice',
json_encode($notice),
self::widget(Options::class)->time + self::widget(Options::class)->timezone + 86400
Options::alloc()->time + Options::alloc()->timezone + 86400
);
Cookie::set(
'__typecho_notice_type',
$type,
self::widget(Options::class)->time + self::widget(Options::class)->timezone + 86400
Options::alloc()->time + Options::alloc()->timezone + 86400
);
}
}

View File

@ -455,7 +455,7 @@ class Options extends Widget
*/
protected function ___loginAction(): string
{
return self::widget(Security::class)->getTokenUrl(
return Security::alloc()->getTokenUrl(
Router::url(
'do',
['action' => 'login', 'widget' => 'Login'],
@ -482,7 +482,7 @@ class Options extends Widget
*/
protected function ___registerAction(): string
{
return self::widget(Security::class)->getTokenUrl(
return Security::alloc()->getTokenUrl(
Router::url('do', ['action' => 'register', 'widget' => 'Register'], $this->index)
);
}
@ -504,7 +504,7 @@ class Options extends Widget
*/
protected function ___logoutUrl(): string
{
return self::widget(Security::class)->getTokenUrl(
return Security::alloc()->getTokenUrl(
Common::url('/action/logout', $this->index)
);
}

View File

@ -1,12 +1,15 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* Typecho Blog Platform
*
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Plugins;
use Typecho\Plugin;
use Typecho\Widget\Exception;
use Typecho\Widget\Helper\Form;
use Widget\Base\Options;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 插件配置组件
@ -17,12 +20,11 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Plugins_Config extends Widget_Abstract_Options
class Config extends Options
{
/**
* 获取插件信息
*
* @access public
* @var array
*/
public $info;
@ -30,45 +32,42 @@ class Widget_Plugins_Config extends Widget_Abstract_Options
/**
* 插件文件路径
*
* @access private
* @var string
*/
private $_pluginFileName;
private $pluginFileName;
/**
* 插件类
*
* @access private
* @var string
*/
private $_className;
private $className;
/**
* 绑定动作
*
* @access public
* @throws Plugin\Exception
* @throws Exception|\Typecho\Db\Exception
*/
public function execute()
{
$this->user->pass('administrator');
$config = $this->request->filter('slug')->config;
if (empty($config)) {
throw new Typecho_Widget_Exception(_t('插件不存在'), 404);
throw new Exception(_t('插件不存在'), 404);
}
/** 获取插件入口 */
[$this->_pluginFileName, $this->_className] = Typecho_Plugin::portal($config,
$this->options->pluginDir($config));
$this->info = Typecho_Plugin::parseInfo($this->_pluginFileName);
[$this->pluginFileName, $this->className] = Plugin::portal($config, $this->options->pluginDir($config));
$this->info = Plugin::parseInfo($this->pluginFileName);
}
/**
* 获取菜单标题
*
* @access public
* @return string
*/
public function getMenuTitle()
public function getMenuTitle(): string
{
return _t('设置插件 %s', $this->info['title']);
}
@ -76,9 +75,8 @@ class Widget_Plugins_Config extends Widget_Abstract_Options
/**
* 配置插件
*
* @access public
* @return Typecho_Widget_Helper_Form
* @throws Typecho_Widget_Exception
* @return Form
* @throws Exception|Plugin\Exception
*/
public function config()
{
@ -86,19 +84,18 @@ class Widget_Plugins_Config extends Widget_Abstract_Options
$pluginName = $this->request->filter('slug')->config;
/** 获取已启用插件 */
$plugins = Typecho_Plugin::export();
$plugins = Plugin::export();
$activatedPlugins = $plugins['activated'];
/** 判断实例化是否成功 */
if (!$this->info['config'] || !isset($activatedPlugins[$pluginName])) {
throw new Typecho_Widget_Exception(_t('无法配置插件'), 500);
throw new Exception(_t('无法配置插件'), 500);
}
/** 载入插件 */
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([$this->_className, 'config'], $form);
require_once $this->pluginFileName;
$form = new Form($this->security->getIndex('/action/plugins-edit?config=' . $pluginName), Form::POST_METHOD);
call_user_func([$this->className, 'config'], $form);
$options = $this->options->plugin($pluginName);
@ -108,7 +105,7 @@ class Widget_Plugins_Config extends Widget_Abstract_Options
}
}
$submit = new Typecho_Widget_Helper_Form_Element_Submit(null, null, _t('保存设置'));
$submit = new Form\Element\Submit(null, null, _t('保存设置'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);
return $form;

View File

@ -1,14 +1,19 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 插件管理
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Plugins;
use Typecho\Common;
use Typecho\Db;
use Typecho\Plugin;
use Typecho\Widget\Exception;
use Typecho\Widget\Helper\Form;
use Widget\ActionInterface;
use Widget\Base\Options;
use Widget\Notice;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 插件管理组件
@ -19,56 +24,60 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Interface_Do
class Edit extends Options implements ActionInterface
{
/**
* @var bool
*/
private $_configNoticed = false;
private $configNoticed = false;
/**
* 启用插件
*
* @param $pluginName
* @throws Typecho_Widget_Exception
* @throws Exception|Db\Exception|Plugin\Exception
*/
public function activate($pluginName)
{
/** 获取插件入口 */
[$pluginFileName, $className] = Typecho_Plugin::portal($pluginName, $this->options->pluginDir($pluginName));
$info = Typecho_Plugin::parseInfo($pluginFileName);
[$pluginFileName, $className] = Plugin::portal($pluginName, $this->options->pluginDir($pluginName));
$info = Plugin::parseInfo($pluginFileName);
/** 检测依赖信息 */
if (Typecho_Plugin::checkDependence(Typecho_Common::VERSION, $info['dependence'])) {
if (Plugin::checkDependence(Common::VERSION, $info['dependence'])) {
/** 获取已启用插件 */
$plugins = Typecho_Plugin::export();
$plugins = Plugin::export();
$activatedPlugins = $plugins['activated'];
/** 载入插件 */
require_once $pluginFileName;
/** 判断实例化是否成功 */
if (isset($activatedPlugins[$pluginName]) || !class_exists($className)
|| !method_exists($className, 'activate')) {
throw new Typecho_Widget_Exception(_t('无法启用插件'), 500);
if (
isset($activatedPlugins[$pluginName]) || !class_exists($className)
|| !method_exists($className, 'activate')
) {
throw new Exception(_t('无法启用插件'), 500);
}
try {
$result = call_user_func([$className, 'activate']);
Typecho_Plugin::activate($pluginName);
$this->update(['value' => serialize(Typecho_Plugin::export())],
$this->db->sql()->where('name = ?', 'plugins'));
} catch (Typecho_Plugin_Exception $e) {
Plugin::activate($pluginName);
$this->update(
['value' => serialize(Plugin::export())],
$this->db->sql()->where('name = ?', 'plugins')
);
} catch (Plugin\Exception $e) {
/** 截获异常 */
self::widget('Widget_Notice')->set($e->getMessage(), 'error');
Notice::alloc()->set($e->getMessage(), 'error');
$this->response->goBack();
}
$form = new Typecho_Widget_Helper_Form();
$form = new Form();
call_user_func([$className, 'config'], $form);
$personalForm = new Typecho_Widget_Helper_Form();
$personalForm = new Form();
call_user_func([$className, 'personalConfig'], $personalForm);
$options = $form->getValues();
@ -81,20 +90,17 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte
if ($personalOptions && !$this->personalConfigHandle($className, $personalOptions)) {
self::configPlugin($pluginName, $personalOptions, true);
}
} else {
$result = _t('<a href="%s">%s</a> 无法在此版本的typecho下正常工作', $info['homepage'], $info['title']);
}
/** 设置高亮 */
self::widget('Widget_Notice')->highlight('plugin-' . $pluginName);
Notice::alloc()->highlight('plugin-' . $pluginName);
if (isset($result) && is_string($result)) {
self::widget('Widget_Notice')->set($result, 'notice');
Notice::alloc()->set($result, 'notice');
} else {
self::widget('Widget_Notice')->set(_t('插件已经被启用'), 'success');
Notice::alloc()->set(_t('插件已经被启用'), 'success');
}
$this->response->goBack();
}
@ -107,18 +113,19 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte
* @param array $settings 配置值
* @param boolean $isInit 是否为初始化
* @return boolean
* @throws Plugin\Exception
*/
public function configHandle($pluginName, array $settings, $isInit)
public function configHandle(string $pluginName, array $settings, bool $isInit): bool
{
/** 获取插件入口 */
[$pluginFileName, $className] = Typecho_Plugin::portal($pluginName, $this->options->pluginDir($pluginName));
[$pluginFileName, $className] = 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)) {
self::widget('Widget_Notice')->set($result, 'notice');
$this->_configNoticed = true;
Notice::alloc()->set($result, 'notice');
$this->configNoticed = true;
}
}
@ -133,13 +140,14 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte
/**
* 手动配置插件变量
*
* @param $pluginName 插件名称
* @param string $pluginName 插件名称
* @param array $settings 变量键值对
* @param bool $isPersonal 是否为私人变量
* @throws Db\Exception
*/
public static function configPlugin($pluginName, array $settings, $isPersonal = false)
public static function configPlugin(string $pluginName, array $settings, bool $isPersonal = false)
{
$db = Typecho_Db::get();
$db = Db::get();
$pluginName = ($isPersonal ? '_' : '') . 'plugin:' . $pluginName;
$select = $db->select()->from('table.options')
@ -176,12 +184,11 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte
/**
* 用自有函数处理自定义配置信息
*
* @access public
* @param string $className 类名
* @param array $settings 配置值
* @return boolean
*/
public function personalConfigHandle($className, array $settings)
public function personalConfigHandle(string $className, array $settings): bool
{
if (method_exists($className, 'personalConfigHandle')) {
call_user_func([$className, 'personalConfigHandle'], $settings, true);
@ -194,22 +201,22 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte
/**
* 禁用插件
*
* @param $pluginName
* @throws Typecho_Widget_Exception
* @param string $pluginName
* @throws Db\Exception
* @throws Exception
* @throws Typecho_Plugin_Exception
* @throws Plugin\Exception
*/
public function deactivate($pluginName)
public function deactivate(string $pluginName)
{
/** 获取已启用插件 */
$plugins = Typecho_Plugin::export();
$plugins = Plugin::export();
$activatedPlugins = $plugins['activated'];
$pluginFileExist = true;
try {
/** 获取插件入口 */
[$pluginFileName, $className] = Typecho_Plugin::portal($pluginName, $this->options->pluginDir($pluginName));
} catch (Typecho_Plugin_Exception $e) {
[$pluginFileName, $className] = Plugin::portal($pluginName, $this->options->pluginDir($pluginName));
} catch (Plugin\Exception $e) {
$pluginFileExist = false;
if (!isset($activatedPlugins[$pluginName])) {
@ -219,7 +226,7 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte
/** 判断实例化是否成功 */
if (!isset($activatedPlugins[$pluginName])) {
throw new Typecho_Widget_Exception(_t('无法禁用插件'), 500);
throw new Exception(_t('无法禁用插件'), 500);
}
if ($pluginFileExist) {
@ -228,34 +235,35 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte
require_once $pluginFileName;
/** 判断实例化是否成功 */
if (!isset($activatedPlugins[$pluginName]) || !class_exists($className)
|| !method_exists($className, 'deactivate')) {
throw new Typecho_Widget_Exception(_t('无法禁用插件'), 500);
if (
!isset($activatedPlugins[$pluginName]) || !class_exists($className)
|| !method_exists($className, 'deactivate')
) {
throw new Exception(_t('无法禁用插件'), 500);
}
try {
$result = call_user_func([$className, 'deactivate']);
} catch (Typecho_Plugin_Exception $e) {
} catch (Plugin\Exception $e) {
/** 截获异常 */
self::widget('Widget_Notice')->set($e->getMessage(), 'error');
Notice::alloc()->set($e->getMessage(), 'error');
$this->response->goBack();
}
/** 设置高亮 */
self::widget('Widget_Notice')->highlight('plugin-' . $pluginName);
Notice::alloc()->highlight('plugin-' . $pluginName);
}
Typecho_Plugin::deactivate($pluginName);
$this->update(['value' => serialize(Typecho_Plugin::export())],
$this->db->sql()->where('name = ?', 'plugins'));
Plugin::deactivate($pluginName);
$this->update(['value' => serialize(Plugin::export())], $this->db->sql()->where('name = ?', 'plugins'));
$this->delete($this->db->sql()->where('name = ?', 'plugin:' . $pluginName));
$this->delete($this->db->sql()->where('name = ?', '_plugin:' . $pluginName));
if (isset($result) && is_string($result)) {
self::widget('Widget_Notice')->set($result, 'notice');
Notice::alloc()->set($result, 'notice');
} else {
self::widget('Widget_Notice')->set(_t('插件已经被禁用'), 'success');
Notice::alloc()->set(_t('插件已经被禁用'), 'success');
}
$this->response->goBack();
}
@ -263,13 +271,14 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte
/**
* 配置插件
*
* @param $pluginName
* @access public
* @return void
* @param string $pluginName
* @throws Db\Exception
* @throws Exception
* @throws Plugin\Exception
*/
public function config($pluginName)
public function config(string $pluginName)
{
$form = self::widget('Widget_Plugins_Config')->config();
$form = Config::alloc()->config();
/** 验证表单 */
if ($form->validate()) {
@ -283,22 +292,19 @@ class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Inte
}
/** 设置高亮 */
self::widget('Widget_Notice')->highlight('plugin-' . $pluginName);
Notice::alloc()->highlight('plugin-' . $pluginName);
if (!$this->_configNoticed) {
if (!$this->configNoticed) {
/** 提示信息 */
self::widget('Widget_Notice')->set(_t("插件设置已经保存"), 'success');
Notice::alloc()->set(_t("插件设置已经保存"), 'success');
}
/** 转向原页 */
$this->response->redirect(Typecho_Common::url('plugins.php', $this->options->adminUrl));
$this->response->redirect(Common::url('plugins.php', $this->options->adminUrl));
}
/**
* 绑定动作
*
* @access public
* @return void
*/
public function action()
{

View File

@ -1,12 +1,14 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* Typecho Blog Platform
*
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Plugins;
use Typecho\Common;
use Typecho\Plugin;
use Typecho\Widget;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 插件列表组件
@ -17,7 +19,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Plugins_List extends Typecho_Widget
class Rows extends Widget
{
/**
* 已启用插件
@ -40,7 +42,7 @@ class Widget_Plugins_List extends Typecho_Widget
$this->parameter->setDefault(['activated' => null]);
/** 获取已启用插件 */
$plugins = Typecho_Plugin::export();
$plugins = Plugin::export();
$this->activatedPlugins = $plugins['activated'];
if (!empty($pluginDirs)) {
@ -53,11 +55,11 @@ class Widget_Plugins_List extends Typecho_Widget
[$pluginName, $pluginFileName] = $parts;
if (file_exists($pluginFileName)) {
$info = Typecho_Plugin::parseInfo($pluginFileName);
$info = Plugin::parseInfo($pluginFileName);
$info['name'] = $pluginName;
$info['dependence'] = Typecho_Plugin::checkDependence(
Typecho_Common::VERSION,
$info['dependence'] = Plugin::checkDependence(
Common::VERSION,
$info['dependence']
);
@ -83,7 +85,7 @@ class Widget_Plugins_List extends Typecho_Widget
/**
* @return array
*/
protected function getPlugins()
protected function getPlugins(): array
{
return glob(__TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__ . '/*');
}
@ -93,7 +95,7 @@ class Widget_Plugins_List extends Typecho_Widget
* @param string $index
* @return array|null
*/
protected function getPlugin($plugin, $index)
protected function getPlugin(string $plugin, string $index): ?array
{
if (is_dir($plugin)) {
/** 获取插件名称 */

View File

@ -1,5 +1,16 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
namespace Widget;
use Typecho\Common;
use Typecho\Cookie;
use Typecho\Db\Exception;
use Typecho\Validate;
use Widget\Base\Users;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 注册组件
@ -8,13 +19,12 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @category typecho
* @package Widget
*/
class Widget_Register extends Widget_Abstract_Users implements Widget_Interface_Do
class Register extends Users implements ActionInterface
{
/**
* 初始化函数
*
* @access public
* @return void
* @throws Exception
*/
public function action()
{
@ -28,7 +38,7 @@ class Widget_Register extends Widget_Abstract_Users implements Widget_Interface_
}
/** 初始化验证类 */
$validator = new Typecho_Validate();
$validator = new Validate();
$validator->addRule('name', 'required', _t('必须填写用户名称'));
$validator->addRule('name', 'minLength', _t('用户名至少包含2个字符'), 2);
$validator->addRule('name', 'maxLength', _t('用户名最多包含32个字符'), 32);
@ -49,16 +59,16 @@ class Widget_Register extends Widget_Abstract_Users implements Widget_Interface_
/** 截获验证异常 */
if ($error = $validator->run($this->request->from('name', 'password', 'mail', 'confirm'))) {
Typecho_Cookie::set('__typecho_remember_name', $this->request->name);
Typecho_Cookie::set('__typecho_remember_mail', $this->request->mail);
Cookie::set('__typecho_remember_name', $this->request->name);
Cookie::set('__typecho_remember_mail', $this->request->mail);
/** 设置提示信息 */
self::widget('Widget_Notice')->set($error);
Notice::alloc()->set($error);
$this->response->goBack();
}
$hasher = new PasswordHash(8, true);
$generatedPassword = Typecho_Common::randString(7);
$hasher = new \PasswordHash(8, true);
$generatedPassword = Common::randString(7);
$dataStruct = [
'name' => $this->request->name,
@ -79,11 +89,18 @@ class Widget_Register extends Widget_Abstract_Users implements Widget_Interface_
$this->user->login($this->request->name, $generatedPassword);
Typecho_Cookie::delete('__typecho_first_run');
Typecho_Cookie::delete('__typecho_remember_name');
Typecho_Cookie::delete('__typecho_remember_mail');
Cookie::delete('__typecho_first_run');
Cookie::delete('__typecho_remember_name');
Cookie::delete('__typecho_remember_mail');
self::widget('Widget_Notice')->set(_t('用户 <strong>%s</strong> 已经成功注册, 密码为 <strong>%s</strong>', $this->screenName, $generatedPassword), 'success');
Notice::alloc()->set(
_t(
'用户 <strong>%s</strong> 已经成功注册, 密码为 <strong>%s</strong>',
$this->screenName,
$generatedPassword
),
'success'
);
$this->response->redirect($this->options->adminUrl);
}
}

View File

@ -39,8 +39,8 @@ class Security extends Widget
*/
public function execute()
{
$this->options = self::widget(Options::class);
$user = self::widget(User::class);
$this->options = Options::alloc();
$user = User::alloc();
$this->token = $this->options->secret;
if ($user->hasLogin()) {

View File

@ -53,7 +53,7 @@ class Service extends BaseOptions implements ActionInterface
}
/** 获取post */
$post = self::widget('Widget_Archive', "type=post", "cid={$this->request->cid}");
$post = Archive::alloc("type=post", "cid={$this->request->cid}", false);
if ($post->have() && preg_match_all("|<a[^>]*href=[\"'](.*?)[\"'][^>]*>(.*?)</a>|", $post->text, $matches)) {
$links = array_unique($matches[1]);

View File

@ -1,14 +1,13 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 全局统计
*
* @link typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget;
use Typecho\Db;
use Typecho\Widget;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 全局统计组件
@ -18,42 +17,39 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Stat extends Typecho_Widget
class Stat extends Widget
{
/**
* 用户对象
*
* @access protected
* @var Widget_User
* @var User
*/
protected $user;
/**
* 数据库对象
*
* @access protected
* @var Typecho_Db
* @var Db
*/
protected $db;
/**
* 构造函数,初始化组件
*
* @access public
* @param mixed $request request对象
* @param mixed $response response对象
* @param mixed $params 参数列表
* @return void
* @throws Db\Exception
*/
public function __construct($request, $response, $params = null)
{
parent::__construct($request, $response, $params);
/** 初始化数据库 */
$this->db = Typecho_Db::get();
$this->db = Db::get();
/** 初始化常用组件 */
$this->user = self::widget('Widget_User');
$this->user = User::alloc();
}
/**

View File

@ -1,12 +1,16 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* Typecho Blog Platform
*
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Themes;
use Typecho\Widget\Exception;
use Typecho\Widget\Helper\Form;
use Typecho\Widget\Helper\Form\Element\Submit;
use Widget\Base\Options as BaseOptions;
use Widget\Options;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 皮肤配置组件
@ -17,33 +21,30 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Themes_Config extends Widget_Abstract_Options
class Config extends BaseOptions
{
/**
* 绑定动作
*
* @access public
* @return void
* @throws Typecho_Widget_Exception
* @throws Exception|\Typecho\Db\Exception
*/
public function execute()
{
$this->user->pass('administrator');
if (!self::isExists()) {
throw new Typecho_Widget_Exception(_t('外观配置功能不存在'), 404);
throw new Exception(_t('外观配置功能不存在'), 404);
}
}
/**
* 配置功能是否存在
*
* @access public
* @return boolean
*/
public static function isExists()
public static function isExists(): bool
{
$options = Typecho_Widget::widget('Widget_Options');
$options = Options::alloc();
$configFile = $options->themeFile($options->theme, 'functions.php');
if (file_exists($configFile)) {
@ -60,13 +61,11 @@ class Widget_Themes_Config extends Widget_Abstract_Options
/**
* 配置外观
*
* @access public
* @return Typecho_Widget_Helper_Form
* @return Form
*/
public function config()
public function config(): Form
{
$form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/themes-edit?config'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getIndex('/action/themes-edit?config'), Form::POST_METHOD);
themeConfig($form);
$inputs = $form->getInputs();
@ -76,7 +75,7 @@ class Widget_Themes_Config extends Widget_Abstract_Options
}
}
$submit = new Typecho_Widget_Helper_Form_Element_Submit(null, null, _t('保存设置'));
$submit = new Submit(null, null, _t('保存设置'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);
return $form;

View File

@ -1,14 +1,17 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 编辑风格
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Themes;
use Typecho\Common;
use Typecho\Widget\Exception;
use Typecho\Widget\Helper\Form;
use Widget\ActionInterface;
use Widget\Base\Options;
use Widget\Notice;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 编辑风格组件
@ -19,17 +22,16 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Interface_Do
class Edit extends Options implements ActionInterface
{
/**
* 更换外观
*
* @access public
* @param string $theme 外观名称
* @return void
* @throws Typecho_Widget_Exception
* @throws Exception
* @throws \Typecho\Db\Exception
*/
public function changeTheme($theme)
public function changeTheme(string $theme)
{
$theme = trim($theme, './');
if (is_dir($this->options->themeFile($theme))) {
@ -49,7 +51,7 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter
require_once $configFile;
if (function_exists('themeConfig')) {
$form = new Typecho_Widget_Helper_Form();
$form = new Form();
themeConfig($form);
$options = $form->getValues();
@ -63,23 +65,22 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter
}
}
self::widget('Widget_Notice')->highlight('theme-' . $theme);
self::widget('Widget_Notice')->set(_t("外观已经改变"), 'success');
Notice::alloc()->highlight('theme-' . $theme);
Notice::alloc()->set(_t("外观已经改变"), 'success');
$this->response->goBack();
} else {
throw new Typecho_Widget_Exception(_t('您选择的风格不存在'));
throw new Exception(_t('您选择的风格不存在'));
}
}
/**
* 用自有函数处理配置信息
*
* @access public
* @param array $settings 配置值
* @param boolean $isInit 是否为初始化
* @return boolean
*/
public function configHandle(array $settings, $isInit)
public function configHandle(array $settings, bool $isInit): bool
{
if (function_exists('themeConfigHandle')) {
themeConfigHandle($settings, $isInit);
@ -92,42 +93,41 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter
/**
* 编辑外观文件
*
* @access public
* @param string $theme 外观名称
* @param string $file 文件名
* @return void
* @throws Typecho_Widget_Exception
* @throws Exception
*/
public function editThemeFile($theme, $file)
{
$path = $this->options->themeFile($theme, $file);
if (file_exists($path) && is_writeable($path)
&& (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__)) {
if (
file_exists($path) && is_writeable($path)
&& (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__)
) {
$handle = fopen($path, 'wb');
if ($handle && fwrite($handle, $this->request->content)) {
fclose($handle);
self::widget('Widget_Notice')->set(_t("文件 %s 的更改已经保存", $file), 'success');
Notice::alloc()->set(_t("文件 %s 的更改已经保存", $file), 'success');
} else {
self::widget('Widget_Notice')->set(_t("文件 %s 无法被写入", $file), 'error');
Notice::alloc()->set(_t("文件 %s 无法被写入", $file), 'error');
}
$this->response->goBack();
} else {
throw new Typecho_Widget_Exception(_t('您编辑的文件不存在'));
throw new Exception(_t('您编辑的文件不存在'));
}
}
/**
* 配置外观
*
* @access public
* @param string $theme 外观名
* @return void
* @throws \Typecho\Db\Exception
*/
public function config($theme)
public function config(string $theme)
{
// 已经载入了外观函数
$form = self::widget('Widget_Themes_Config')->config();
$form = Config::alloc()->config();
/** 验证表单 */
if ($form->validate()) {
@ -138,8 +138,10 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter
if (!$this->configHandle($settings, false)) {
if ($this->options->__get('theme:' . $theme)) {
$this->update(['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([
'name' => 'theme:' . $theme,
@ -150,20 +152,19 @@ class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Inter
}
/** 设置高亮 */
self::widget('Widget_Notice')->highlight('theme-' . $theme);
Notice::alloc()->highlight('theme-' . $theme);
/** 提示信息 */
self::widget('Widget_Notice')->set(_t("外观设置已经保存"), 'success');
Notice::alloc()->set(_t("外观设置已经保存"), 'success');
/** 转向原页 */
$this->response->redirect(Typecho_Common::url('options-theme.php', $this->options->adminUrl));
$this->response->redirect(Common::url('options-theme.php', $this->options->adminUrl));
}
/**
* 绑定动作
*
* @access public
* @return void
* @throws Exception|\Typecho\Db\Exception
*/
public function action()
{

View File

@ -1,14 +1,13 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 风格文件列表
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Themes;
use Typecho\Widget;
use Widget\Options;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 风格文件列表组件
@ -19,7 +18,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Themes_Files extends Typecho_Widget
class Files extends Widget
{
/**
* 当前风格
@ -27,7 +26,7 @@ class Widget_Themes_Files extends Typecho_Widget
* @access private
* @var string
*/
private $_currentTheme;
private $currentTheme;
/**
* 当前文件
@ -35,40 +34,41 @@ class Widget_Themes_Files extends Typecho_Widget
* @access private
* @var string
*/
private $_currentFile;
private $currentFile;
/**
* 执行函数
*
* @access public
* @return void
* @throws Typecho_Widget_Exception
* @throws Widget\Exception
*/
public function execute()
{
/** 管理员权限 */
self::widget('Widget_User')->pass('administrator');
$this->_currentTheme = $this->request->filter('slug')->get('theme', self::widget('Widget_Options')->theme);
if (preg_match("/^([_0-9a-z-\.\ ])+$/i", $this->_currentTheme)
&& is_dir($dir = self::widget('Widget_Options')->themeFile($this->_currentTheme))
&& (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__)) {
$this->currentTheme = $this->request->filter('slug')->get('theme', Options::alloc()->theme);
if (
preg_match("/^([_0-9a-z-\.\ ])+$/i", $this->currentTheme)
&& is_dir($dir = Options::alloc()->themeFile($this->currentTheme))
&& (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__)
) {
$files = array_filter(glob($dir . '/*'), function ($path) {
return preg_match("/\.(php|js|css|vbs)$/i", $path);
});
$this->_currentFile = $this->request->get('file', 'index.php');
$this->currentFile = $this->request->get('file', 'index.php');
if (preg_match("/^([_0-9a-z-\.\ ])+$/i", $this->_currentFile)
&& file_exists($dir . '/' . $this->_currentFile)) {
if (
preg_match("/^([_0-9a-z-\.\ ])+$/i", $this->currentFile)
&& file_exists($dir . '/' . $this->currentFile)
) {
foreach ($files as $file) {
if (file_exists($file)) {
$file = basename($file);
$this->push([
'file' => $file,
'theme' => $this->_currentTheme,
'current' => ($file == $this->_currentFile)
'theme' => $this->currentTheme,
'current' => ($file == $this->currentFile)
]);
}
}
@ -77,64 +77,59 @@ class Widget_Themes_Files extends Typecho_Widget
}
}
throw new Typecho_Widget_Exception('风格文件不存在', 404);
throw new Widget\Exception('风格文件不存在', 404);
}
/**
* 获取菜单标题
*
* @access public
* @return string
*/
public function getMenuTitle()
public function getMenuTitle(): string
{
return _t('编辑文件 %s', $this->_currentFile);
return _t('编辑文件 %s', $this->currentFile);
}
/**
* 获取文件内容
*
* @access public
* @return string
*/
public function currentContent()
public function currentContent(): string
{
return htmlspecialchars(file_get_contents(self::widget('Widget_Options')
->themeFile($this->_currentTheme, $this->_currentFile)));
return htmlspecialchars(file_get_contents(Options::alloc()
->themeFile($this->currentTheme, $this->currentFile)));
}
/**
* 获取文件是否可读
*
* @access public
* @return string
* @return bool
*/
public function currentIsWriteable()
public function currentIsWriteable(): bool
{
return is_writeable(self::widget('Widget_Options')
->themeFile($this->_currentTheme, $this->_currentFile))
return is_writeable(Options::alloc()
->themeFile($this->currentTheme, $this->currentFile))
&& (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__);
}
/**
* 获取当前文件
*
* @access public
* @return string
*/
public function currentFile()
public function currentFile(): string
{
return $this->_currentFile;
return $this->currentFile;
}
/**
* 获取当前风格
*
* @access public
* @return string
*/
public function currentTheme()
public function currentTheme(): string
{
return $this->_currentTheme;
return $this->currentTheme;
}
}

View File

@ -1,14 +1,15 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 风格列表
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Themes;
use Typecho\Common;
use Typecho\Plugin;
use Typecho\Widget;
use Widget\Options;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 风格列表组件
@ -19,27 +20,24 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Themes_List extends Typecho_Widget
class Rows extends Widget
{
/**
* 执行函数
*
* @access public
* @return void
*/
public function execute()
{
$themes = $this->getThemes();
if ($themes) {
$options = self::widget('Widget_Options');
$options = Options::alloc();
$activated = 0;
$result = [];
foreach ($themes as $key => $theme) {
$themeFile = $theme . '/index.php';
if (file_exists($themeFile)) {
$info = Typecho_Plugin::parseInfo($themeFile);
$info = Plugin::parseInfo($themeFile);
$info['name'] = $this->getTheme($theme, $key);
if ($info['activated'] = ($options->theme == $info['name'])) {
@ -53,7 +51,7 @@ class Widget_Themes_List extends Typecho_Widget
if ($screen) {
$info['screen'] = $options->themeUrl(basename(current($screen)), $info['name']);
} else {
$info['screen'] = Typecho_Common::url('noscreen.png', $options->adminStaticUrl('img'));
$info['screen'] = Common::url('noscreen.png', $options->adminStaticUrl('img'));
}
$result[$key] = $info;
@ -70,7 +68,7 @@ class Widget_Themes_List extends Typecho_Widget
/**
* @return array
*/
protected function getThemes()
protected function getThemes(): array
{
return glob(__TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/*', GLOB_ONLYDIR);
}
@ -82,7 +80,7 @@ class Widget_Themes_List extends Typecho_Widget
* @param mixed $index
* @return string
*/
protected function getTheme($theme, $index)
protected function getTheme(string $theme, $index): string
{
return basename($theme);
}

View File

@ -1,14 +1,14 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 升级动作
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget;
use Typecho\Common;
use Typecho\Exception;
use Widget\Base\Options as BaseOptions;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 升级组件
@ -17,14 +17,12 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @category typecho
* @package Widget
*/
class Widget_Upgrade extends Widget_Abstract_Options implements Widget_Interface_Do
class Upgrade extends BaseOptions implements ActionInterface
{
/**
* 执行升级程序
*
* @access public
* @return void
* @throws Typecho_Exception
* @throws \Typecho\Db\Exception
*/
public function upgrade()
{
@ -51,15 +49,17 @@ class Widget_Upgrade extends Widget_Abstract_Options implements Widget_Interface
if (isset($matches[2])) {
$minor = substr(str_replace('_', '.', $matches[2]), 1);
if (version_compare($currentVersion, $version, '=')
&& version_compare($currentMinor, $minor, '>=')) {
if (
version_compare($currentVersion, $version, '=')
&& version_compare($currentMinor, $minor, '>=')
) {
break;
}
$version .= '/' . $minor;
}
$options = self::widget('Widget_Options@' . $package);
$options = Options::allocWithAlias($package);
/** 执行升级脚本 */
try {
@ -67,32 +67,38 @@ class Widget_Upgrade extends Widget_Abstract_Options implements Widget_Interface
if (!empty($result)) {
$message[] = $result;
}
} catch (Typecho_Exception $e) {
self::widget('Widget_Notice')->set($e->getMessage(), 'error');
} catch (Exception $e) {
Notice::alloc()->set($e->getMessage(), 'error');
$this->response->goBack();
return;
}
/** 更新版本号 */
$this->update(['value' => 'Typecho ' . $version],
$this->db->sql()->where('name = ?', 'generator'));
$this->update(
['value' => 'Typecho ' . $version],
$this->db->sql()->where('name = ?', 'generator')
);
$this->destroy('Widget_Options@' . $package);
Options::destroy($package);
}
/** 更新版本号 */
$this->update(['value' => 'Typecho ' . Typecho_Common::VERSION],
$this->db->sql()->where('name = ?', 'generator'));
$this->update(
['value' => 'Typecho ' . Common::VERSION],
$this->db->sql()->where('name = ?', 'generator')
);
self::widget('Widget_Notice')->set(empty($message) ? _t("升级已经完成") : $message,
empty($message) ? 'success' : 'notice');
Notice::alloc()->set(
empty($message) ? _t("升级已经完成") : $message,
empty($message) ? 'success' : 'notice'
);
}
/**
* 初始化函数
*
* @access public
* @return void
* @throws \Typecho\Db\Exception
* @throws \Typecho\Widget\Exception
*/
public function action()
{

View File

@ -54,7 +54,7 @@ class Upload extends Contents implements ActionInterface
return $result;
}
$options = self::widget(Options::class);
$options = Options::alloc();
return Common::url(
$content['attachment']->path,
defined('__TYPECHO_UPLOAD_URL__') ? __TYPECHO_UPLOAD_URL__ : $options->siteUrl
@ -431,7 +431,7 @@ class Upload extends Contents implements ActionInterface
*/
public static function checkFileType($ext)
{
$options = self::widget(Options::class);
$options = Options::alloc();
return in_array($ext, $options->allowedAttachmentTypes);
}
}

View File

@ -79,7 +79,7 @@ class User extends Widget
/** 初始化数据库 */
$this->db = Db::get();
$this->options = self::widget(Options::class);
$this->options = Options::alloc();
}

View File

@ -1,12 +1,17 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* Typecho Blog Platform
*
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Users;
use Typecho\Common;
use Typecho\Db;
use Typecho\Db\Query;
use Typecho\Widget\Exception;
use Typecho\Widget\Helper\PageNavigator\Box;
use Widget\Base\Users;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 后台成员列表组件
@ -17,55 +22,53 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Users_Admin extends Widget_Abstract_Users
class Admin extends Users
{
/**
* 分页计算对象
*
* @access private
* @var Typecho_Db_Query
* @var Query
*/
private $_countSql;
private $countSql;
/**
* 所有文章个数
*
* @access private
* @var integer
*/
private $_total = false;
private $total;
/**
* 当前页
*
* @access private
* @var integer
*/
private $_currentPage;
private $currentPage;
/**
* 执行函数
*
* @access public
* @return void
* @throws Db\Exception
*/
public function execute()
{
$this->parameter->setDefault('pageSize=20');
$select = $this->select();
$this->_currentPage = $this->request->get('page', 1);
$this->currentPage = $this->request->get('page', 1);
/** 过滤标题 */
if (null != ($keywords = $this->request->keywords)) {
$select->where('name LIKE ? OR screenName LIKE ?',
'%' . Typecho_Common::filterSearchQuery($keywords) . '%',
'%' . Typecho_Common::filterSearchQuery($keywords) . '%');
$select->where(
'name LIKE ? OR screenName LIKE ?',
'%' . Common::filterSearchQuery($keywords) . '%',
'%' . Common::filterSearchQuery($keywords) . '%'
);
}
$this->_countSql = clone $select;
$this->countSql = clone $select;
$select->order('table.users.uid', Typecho_Db::SORT_ASC)
->page($this->_currentPage, $this->parameter->pageSize);
$select->order('table.users.uid', Db::SORT_ASC)
->page($this->currentPage, $this->parameter->pageSize);
$this->db->fetchAll($select, [$this, 'push']);
}
@ -73,26 +76,28 @@ class Widget_Users_Admin extends Widget_Abstract_Users
/**
* 输出分页
*
* @access public
* @return void
* @throws Exception|Db\Exception
*/
public function pageNav()
{
$query = $this->request->makeUriByRequest('page={page}');;
$query = $this->request->makeUriByRequest('page={page}');
/** 使用盒状分页 */
$nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total,
$this->_currentPage, $this->parameter->pageSize, $query);
$nav = new Box(
!isset($this->total) ? $this->total = $this->size($this->countSql) : $this->total,
$this->currentPage,
$this->parameter->pageSize,
$query
);
$nav->render('&laquo;', '&raquo;');
}
/**
* 仅仅输出域名和路径
*
* @access protected
* @return string
*/
protected function ___domainPath()
protected function ___domainPath(): string
{
$parts = parse_url($this->url);
return $parts['host'] . ($parts['path'] ?? null);
@ -101,10 +106,10 @@ class Widget_Users_Admin extends Widget_Abstract_Users
/**
* 发布文章数
*
* @access protected
* @return integer
* @throws Db\Exception
*/
protected function ___postsNum()
protected function ___postsNum(): int
{
return $this->db->fetchObject($this->db->select(['COUNT(cid)' => 'num'])
->from('table.contents')

View File

@ -1,14 +1,17 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 编辑用户
*
* @link typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Users;
use Typecho\Common;
use Typecho\Widget\Exception;
use Typecho\Widget\Helper\Form;
use Widget\ActionInterface;
use Widget\Base\Users;
use Widget\Notice;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 编辑用户组件
@ -18,13 +21,13 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interface_Do
class Edit extends Users implements ActionInterface
{
/**
* 执行函数
*
* @access public
* @return void
* @throws Exception|\Typecho\Db\Exception
*/
public function execute()
{
@ -37,7 +40,7 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
->where('uid = ?', $this->request->uid)->limit(1), [$this, 'push']);
if (!$this->have()) {
throw new Typecho_Widget_Exception(_t('用户不存在'), 404);
throw new Exception(_t('用户不存在'), 404);
}
}
}
@ -45,10 +48,9 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
/**
* 获取菜单标题
*
* @access public
* @return string
*/
public function getMenuTitle()
public function getMenuTitle(): string
{
return _t('编辑用户 %s', $this->name);
}
@ -56,11 +58,11 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
/**
* 判断用户是否存在
*
* @access public
* @param integer $uid 用户主键
* @return boolean
* @throws \Typecho\Db\Exception
*/
public function userExists($uid)
public function userExists(int $uid): bool
{
$user = $this->db->fetchRow($this->db->select()
->from('table.users')
@ -72,8 +74,7 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
/**
* 增加用户
*
* @access public
* @return void
* @throws \Typecho\Db\Exception
*/
public function insertUser()
{
@ -81,7 +82,7 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
$this->response->goBack();
}
$hasher = new PasswordHash(8, true);
$hasher = new \PasswordHash(8, true);
/** 取出数据 */
$user = $this->request->from('name', 'mail', 'screenName', 'password', 'url', 'group');
@ -93,77 +94,80 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
$user['uid'] = $this->insert($user);
/** 设置高亮 */
self::widget('Widget_Notice')->highlight('user-' . $user['uid']);
Notice::alloc()->highlight('user-' . $user['uid']);
/** 提示信息 */
self::widget('Widget_Notice')->set(_t('用户 %s 已经被增加', $user['screenName']), 'success');
Notice::alloc()->set(_t('用户 %s 已经被增加', $user['screenName']), 'success');
/** 转向原页 */
$this->response->redirect(Typecho_Common::url('manage-users.php', $this->options->adminUrl));
$this->response->redirect(Common::url('manage-users.php', $this->options->adminUrl));
}
/**
* 生成表单
*
* @access public
* @param string $action 表单动作
* @return Typecho_Widget_Helper_Form
* @param string|null $action 表单动作
* @return Form
*/
public function form($action = null)
public function form(?string $action = null): Form
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-edit'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getIndex('/action/users-edit'), Form::POST_METHOD);
/** 用户名称 */
$name = new Typecho_Widget_Helper_Form_Element_Text('name', null, null, _t('用户名') . ' *', _t('此用户名将作为用户登录时所用的名称.')
$name = new 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('电子邮箱地址将作为此用户的主要联系方式.')
$mail = new 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('用户昵称可以与用户名不同, 用于前台显示.')
$screenName = new 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('为此用户分配一个密码.')
$password = new 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 = new 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> 开头.'));
$url = new 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>.'));
$group = new 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');
$do = new Form\Element\Hidden('do');
$form->addInput($do);
/** 用户主键 */
$uid = new Typecho_Widget_Helper_Form_Element_Hidden('uid');
$uid = new Form\Element\Hidden('uid');
$form->addInput($uid);
/** 提交按钮 */
$submit = new Typecho_Widget_Helper_Form_Element_Submit();
$submit = new Form\Element\Submit();
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);
@ -220,8 +224,7 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
/**
* 更新用户
*
* @access public
* @return void
* @throws \Typecho\Db\Exception
*/
public function updateUser()
{
@ -235,7 +238,7 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
if (empty($user['password'])) {
unset($user['password']);
} else {
$hasher = new PasswordHash(8, true);
$hasher = new \PasswordHash(8, true);
$user['password'] = $hasher->HashPassword($user['password']);
}
@ -243,24 +246,24 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
$this->update($user, $this->db->sql()->where('uid = ?', $this->request->uid));
/** 设置高亮 */
self::widget('Widget_Notice')->highlight('user-' . $this->request->uid);
Notice::alloc()->highlight('user-' . $this->request->uid);
/** 提示信息 */
self::widget('Widget_Notice')->set(_t('用户 %s 已经被更新', $user['screenName']), 'success');
Notice::alloc()->set(_t('用户 %s 已经被更新', $user['screenName']), 'success');
/** 转向原页 */
$this->response->redirect(Typecho_Common::url('manage-users.php?' .
$this->response->redirect(Common::url('manage-users.php?' .
$this->getPageOffsetQuery($this->request->uid), $this->options->adminUrl));
}
/**
* 获取页面偏移的URL Query
*
* @access protected
* @param integer $uid 用户id
* @return string
* @throws \Typecho\Db\Exception
*/
protected function getPageOffsetQuery($uid)
protected function getPageOffsetQuery(int $uid): string
{
return 'page=' . $this->getPageOffset('uid', $uid);
}
@ -268,8 +271,7 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
/**
* 删除用户
*
* @access public
* @return void
* @throws \Typecho\Db\Exception
*/
public function deleteUser()
{
@ -283,16 +285,18 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac
}
if ($this->delete($this->db->sql()->where('uid = ?', $user))) {
$deleteCount ++;
$deleteCount++;
}
}
/** 提示信息 */
self::widget('Widget_Notice')->set($deleteCount > 0 ? _t('用户已经删除') : _t('没有用户被删除'),
$deleteCount > 0 ? 'success' : 'notice');
Notice::alloc()->set(
$deleteCount > 0 ? _t('用户已经删除') : _t('没有用户被删除'),
$deleteCount > 0 ? 'success' : 'notice'
);
/** 转向原页 */
$this->response->redirect(Typecho_Common::url('manage-users.php', $this->options->adminUrl));
$this->response->redirect(Common::url('manage-users.php', $this->options->adminUrl));
}
/**

View File

@ -1,14 +1,19 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 编辑用户
*
* @link typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Users;
use Typecho\Common;
use Typecho\Db\Exception;
use Typecho\Plugin;
use Typecho\Widget\Helper\Form;
use Widget\ActionInterface;
use Widget\Base\Options;
use Widget\Notice;
use Widget\Plugins\Rows;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 编辑用户组件
@ -18,13 +23,10 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface_Do
class Profile extends Edit implements ActionInterface
{
/**
* 执行函数
*
* @access public
* @return void
*/
public function execute()
{
@ -37,32 +39,41 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
* 输出表单结构
*
* @access public
* @return Typecho_Widget_Helper_Form
* @return Form
*/
public function optionsForm()
public function optionsForm(): Form
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getIndex('/action/users-profile'), Form::POST_METHOD);
/** 撰写设置 */
$markdown = new Typecho_Widget_Helper_Form_Element_Radio('markdown',
$markdown = new Form\Element\Radio(
'markdown',
['0' => _t('关闭'), '1' => _t('打开')],
$this->options->markdown, _t('使用 Markdown 语法编辑和解析内容'),
$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',
$xmlrpcMarkdown = new Form\Element\Radio(
'xmlrpcMarkdown',
['0' => _t('关闭'), '1' => _t('打开')],
$this->options->xmlrpcMarkdown, _t('在 XMLRPC 接口中使用 Markdown 语法'),
_t('对于完全支持 <a href="http://daringfireball.net/projects/markdown/">Markdown</a> 语法写作的离线编辑器, 打开此选项后将避免内容被转换为 HTML.'));
$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',
$autoSave = new Form\Element\Radio(
'autoSave',
['0' => _t('关闭'), '1' => _t('打开')],
$this->options->autoSave, _t('自动保存'), _t('自动保存功能可以更好地保护你的文章不会丢失.'));
$this->options->autoSave,
_t('自动保存'),
_t('自动保存功能可以更好地保护你的文章不会丢失.')
);
$form->addInput($autoSave);
/** 默认允许 */
@ -79,17 +90,21 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
$allow[] = 'feed';
}
$defaultAllow = new Typecho_Widget_Helper_Form_Element_Checkbox('defaultAllow',
$defaultAllow = new Form\Element\Checkbox(
'defaultAllow',
['comment' => _t('可以被评论'), 'ping' => _t('可以被引用'), 'feed' => _t('出现在聚合中')],
$allow, _t('默认允许'), _t('设置你经常使用的默认允许权限'));
$allow,
_t('默认允许'),
_t('设置你经常使用的默认允许权限')
);
$form->addInput($defaultAllow);
/** 用户动作 */
$do = new Typecho_Widget_Helper_Form_Element_Hidden('do', null, 'options');
$do = new Form\Element\Hidden('do', null, 'options');
$form->addInput($do);
/** 提交按钮 */
$submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置'));
$submit = new Form\Element\Submit('submit', null, _t('保存设置'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);
@ -99,16 +114,18 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
/**
* 自定义设置列表
*
* @access public
* @return void
* @throws Plugin\Exception
*/
public function personalFormList()
{
self::widget('Widget_Plugins_List@personalPlugins', 'activated=1')->to($plugins);
$plugins = Rows::alloc('activated=1');
while ($plugins->next()) {
if ($plugins->personalConfig) {
[$pluginFileName, $className] = Typecho_Plugin::portal($plugins->name,
$this->options->pluginDir($plugins->name));
[$pluginFileName, $className] = Plugin::portal(
$plugins->name,
$this->options->pluginDir($plugins->name)
);
$form = $this->personalForm($plugins->name, $className, $pluginFileName, $group);
if ($this->user->pass($group, true)) {
@ -130,20 +147,19 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
* @param string $pluginName 插件名称
* @param string $className 类名称
* @param string $pluginFileName 插件文件名
* @param string $group 用户组
* @return Typecho_Widget_Helper_Form
* @param string|null $group 用户组
* @throws Plugin\Exception
*/
public function personalForm($pluginName, $className, $pluginFileName, &$group)
public function personalForm(string $pluginName, string $className, string $pluginFileName, ?string &$group)
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getIndex('/action/users-profile'), Form::POST_METHOD);
$form->setAttribute('name', $pluginName);
$form->setAttribute('id', $pluginName);
require_once $pluginFileName;
$group = call_user_func([$className, 'personalConfig'], $form);
$group = $group ? $group : 'subscriber';
$group = $group ?: 'subscriber';
$options = $this->options->personalPlugin($pluginName);
@ -153,9 +169,9 @@ 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 Form\Element\Hidden('do', null, 'personal'));
$form->addItem(new Form\Element\Hidden('plugin', null, $pluginName));
$submit = new Form\Element\Submit('submit', null, _t('保存设置'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);
return $form;
@ -164,8 +180,7 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
/**
* 更新用户
*
* @access public
* @return void
* @throws Exception
*/
public function updateProfile()
{
@ -181,10 +196,10 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
$this->update($user, $this->db->sql()->where('uid = ?', $this->user->uid));
/** 设置高亮 */
self::widget('Widget_Notice')->highlight('user-' . $this->user->uid);
Notice::alloc()->highlight('user-' . $this->user->uid);
/** 提示信息 */
self::widget('Widget_Notice')->set(_t('您的档案已经更新'), 'success');
Notice::alloc()->set(_t('您的档案已经更新'), 'success');
/** 转向原页 */
$this->response->goBack();
@ -193,35 +208,33 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
/**
* 生成表单
*
* @access public
* @return Typecho_Widget_Helper_Form
* @return Form
*/
public function profileForm()
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getIndex('/action/users-profile'), Form::POST_METHOD);
/** 用户昵称 */
$screenName = new Typecho_Widget_Helper_Form_Element_Text('screenName', null, null, _t('昵称'), _t('用户昵称可以与用户名不同, 用于前台显示.')
$screenName = new 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> 开头.'));
$url = new 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('电子邮箱地址将作为此用户的主要联系方式.')
$mail = new Form\Element\Text('mail', null, null, _t('邮件地址') . ' *', _t('电子邮箱地址将作为此用户的主要联系方式.')
. '<br />' . _t('请不要与系统中现有的电子邮箱地址重复.'));
$form->addInput($mail);
/** 用户动作 */
$do = new Typecho_Widget_Helper_Form_Element_Hidden('do', null, 'profile');
$do = new Form\Element\Hidden('do', null, 'profile');
$form->addInput($do);
/** 提交按钮 */
$submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('更新我的档案'));
$submit = new Form\Element\Submit('submit', null, _t('更新我的档案'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);
@ -243,8 +256,7 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
/**
* 执行更新动作
*
* @access public
* @return void
* @throws Exception
*/
public function updateOptions()
{
@ -258,12 +270,17 @@ 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(['COUNT(*)' => 'num'])
->from('table.options')->where('name = ? AND user = ?', $name, $this->user->uid))->num > 0) {
self::widget('Widget_Abstract_Options')
->update(['value' => $value], $this->db->sql()->where('name = ? AND user = ?', $name, $this->user->uid));
if (
$this->db->fetchObject($this->db->select(['COUNT(*)' => 'num'])
->from('table.options')->where('name = ? AND user = ?', $name, $this->user->uid))->num > 0
) {
Options::alloc()
->update(
['value' => $value],
$this->db->sql()->where('name = ? AND user = ?', $name, $this->user->uid)
);
} else {
self::widget('Widget_Abstract_Options')->insert([
Options::alloc()->insert([
'name' => $name,
'value' => $value,
'user' => $this->user->uid
@ -271,15 +288,14 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
}
}
self::widget('Widget_Notice')->set(_t("设置已经保存"), 'success');
Notice::alloc()->set(_t("设置已经保存"), 'success');
$this->response->goBack();
}
/**
* 更新密码
*
* @access public
* @return void
* @throws Exception
*/
public function updatePassword()
{
@ -288,18 +304,20 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
$this->response->goBack();
}
$hasher = new PasswordHash(8, true);
$hasher = new \PasswordHash(8, true);
$password = $hasher->HashPassword($this->request->password);
/** 更新数据 */
$this->update(['password' => $password],
$this->db->sql()->where('uid = ?', $this->user->uid));
$this->update(
['password' => $password],
$this->db->sql()->where('uid = ?', $this->user->uid)
);
/** 设置高亮 */
self::widget('Widget_Notice')->highlight('user-' . $this->user->uid);
Notice::alloc()->highlight('user-' . $this->user->uid);
/** 提示信息 */
self::widget('Widget_Notice')->set(_t('密码已经成功修改'), 'success');
Notice::alloc()->set(_t('密码已经成功修改'), 'success');
/** 转向原页 */
$this->response->goBack();
@ -308,32 +326,30 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
/**
* 生成表单
*
* @access public
* @return Typecho_Widget_Helper_Form
* @return Form
*/
public function passwordForm()
public function passwordForm(): Form
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/users-profile'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getIndex('/action/users-profile'), Form::POST_METHOD);
/** 用户密码 */
$password = new Typecho_Widget_Helper_Form_Element_Password('password', null, null, _t('用户密码'), _t('为此用户分配一个密码.')
$password = new 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 = new 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');
$do = new Form\Element\Hidden('do', null, 'password');
$form->addInput($do);
/** 提交按钮 */
$submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('更新密码'));
$submit = new Form\Element\Submit('submit', null, _t('更新密码'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);
@ -347,8 +363,7 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
/**
* 更新个人设置
*
* @access public
* @return void
* @throws \Typecho\Widget\Exception
*/
public function updatePersonal()
{
@ -356,16 +371,18 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
$pluginName = $this->request->plugin;
/** 获取已启用插件 */
$plugins = Typecho_Plugin::export();
$plugins = Plugin::export();
$activatedPlugins = $plugins['activated'];
/** 获取插件入口 */
[$pluginFileName, $className] = Typecho_Plugin::portal($this->request->plugin,
__TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__);
$info = Typecho_Plugin::parseInfo($pluginFileName);
[$pluginFileName, $className] = Plugin::portal(
$this->request->plugin,
__TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__
);
$info = Plugin::parseInfo($pluginFileName);
if (!$info['personalConfig'] || !isset($activatedPlugins[$pluginName])) {
throw new Typecho_Widget_Exception(_t('无法配置插件'), 500);
throw new \Typecho\Widget\Exception(_t('无法配置插件'), 500);
}
$form = $this->personalForm($pluginName, $className, $pluginFileName, $group);
@ -381,12 +398,17 @@ 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(['COUNT(*)' => 'num'])
->from('table.options')->where('name = ? AND user = ?', $name, $this->user->uid))->num > 0) {
self::widget('Widget_Abstract_Options')
->update(['value' => serialize($settings)], $this->db->sql()->where('name = ? AND user = ?', $name, $this->user->uid));
if (
$this->db->fetchObject($this->db->select(['COUNT(*)' => 'num'])
->from('table.options')->where('name = ? AND user = ?', $name, $this->user->uid))->num > 0
) {
Options::alloc()
->update(
['value' => serialize($settings)],
$this->db->sql()->where('name = ? AND user = ?', $name, $this->user->uid)
);
} else {
self::widget('Widget_Abstract_Options')->insert([
Options::alloc()->insert([
'name' => $name,
'value' => serialize($settings),
'user' => $this->user->uid
@ -395,10 +417,10 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
}
/** 提示信息 */
self::widget('Widget_Notice')->set(_t("%s 设置已经保存", $info['title']), 'success');
Notice::alloc()->set(_t("%s 设置已经保存", $info['title']), 'success');
/** 转向原页 */
$this->response->redirect(Typecho_Common::url('profile.php', $this->options->adminUrl));
$this->response->redirect(Common::url('profile.php', $this->options->adminUrl));
}
/**
@ -409,7 +431,7 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface
* @param array $settings 配置值
* @return boolean
*/
public function personalConfigHandle($className, array $settings)
public function personalConfigHandle(string $className, array $settings): bool
{
if (method_exists($className, 'personalConfigHandle')) {
call_user_func([$className, 'personalConfigHandle'], $settings, false);