mirror of
https://github.com/typecho/typecho.git
synced 2025-01-17 20:48:42 +01:00
commit
5303124431
@ -6,3 +6,6 @@ indent_size = 4
|
||||
|
||||
[*.scss]
|
||||
indent_size = 2
|
||||
|
||||
[*.php]
|
||||
insert_final_newline = true
|
48
.phpstorm.meta.php
Normal file
48
.phpstorm.meta.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace PHPSTORM_META {
|
||||
override(\Typecho\Widget::widget(0), map([
|
||||
'' => '@'
|
||||
]));
|
||||
|
||||
exitPoint(\Typecho\Widget\Response::redirect());
|
||||
exitPoint(\Typecho\Widget\Response::throwContent());
|
||||
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,
|
||||
'feedRssUrl' => string,
|
||||
'feedAtomUrl' => string,
|
||||
'commentsFeedUrl' => string,
|
||||
'commentsFeedRssUrl' => string,
|
||||
'commentsFeedAtomUrl' => string,
|
||||
'xmlRpcUrl' => string,
|
||||
'index' => string,
|
||||
'siteUrl' => string,
|
||||
'routingTable' => \ArrayObject::class,
|
||||
'rootUrl' => string,
|
||||
'themeUrl' => string,
|
||||
'pluginUrl' => string,
|
||||
'adminUrl' => string,
|
||||
'loginUrl' => string,
|
||||
'loginAction' => string,
|
||||
'registerUrl' => string,
|
||||
'registerAction' => string,
|
||||
'profileUrl' => string,
|
||||
'logoutUrl' => string,
|
||||
'serverTimezone' => int,
|
||||
'contentType' => string,
|
||||
'software' => string,
|
||||
'version' => string,
|
||||
'markdown' => int,
|
||||
'allowedAttachmentTypes'=> \ArrayObject::class
|
||||
]));
|
||||
|
||||
override(\Typecho\Widget::__get(0), map([
|
||||
'sequence' => int,
|
||||
'length' => int
|
||||
]));
|
||||
}
|
@ -4,10 +4,10 @@ include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
$actionUrl = $security->getTokenUrl(
|
||||
Typecho_Router::url('do', array('action' => 'backup', 'widget' => 'Backup'),
|
||||
Typecho_Common::url('index.php', $options->rootUrl)));
|
||||
\Typecho\Router::url('do', array('action' => 'backup', 'widget' => 'Backup'),
|
||||
\Typecho\Common::url('index.php', $options->rootUrl)));
|
||||
|
||||
$backupFiles = Typecho_Widget::widget('Widget_Backup')->listFiles();
|
||||
$backupFiles = \Widget\Backup::alloc()->listFiles();
|
||||
?>
|
||||
|
||||
<div class="main">
|
||||
|
@ -9,7 +9,7 @@ include 'menu.php';
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main" role="form">
|
||||
<div class="col-mb-12 col-tb-6 col-tb-offset-3">
|
||||
<?php Typecho_Widget::widget('Widget_Metas_Category_Edit')->form()->render(); ?>
|
||||
<?php \Widget\Metas\Category\Edit::alloc()->form()->render(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,13 +7,13 @@
|
||||
$(document).ready(function() {
|
||||
// 处理消息机制
|
||||
(function () {
|
||||
var prefix = '<?php echo Typecho_Cookie::getPrefix(); ?>',
|
||||
var prefix = '<?php echo \Typecho\Cookie::getPrefix(); ?>',
|
||||
cookies = {
|
||||
notice : $.cookie(prefix + '__typecho_notice'),
|
||||
noticeType : $.cookie(prefix + '__typecho_notice_type'),
|
||||
highlight : $.cookie(prefix + '__typecho_notice_highlight')
|
||||
},
|
||||
path = '<?php echo Typecho_Cookie::getPath(); ?>';
|
||||
path = '<?php echo \Typecho\Cookie::getPath(); ?>';
|
||||
|
||||
if (!!cookies.notice && 'success|notice|error'.indexOf(cookies.noticeType) >= 0) {
|
||||
var head = $('.typecho-head-nav'),
|
||||
@ -110,7 +110,7 @@
|
||||
|
||||
if ((href && href[0] == '#')
|
||||
|| /^<?php echo preg_quote($options->adminUrl, '/'); ?>.*$/.exec(href)
|
||||
|| /^<?php echo substr(preg_quote(Typecho_Common::url('s', $options->index), '/'), 0, -1); ?>action\/[_a-zA-Z0-9\/]+.*$/.exec(href)) {
|
||||
|| /^<?php echo substr(preg_quote(\Typecho\Common::url('s', $options->index), '/'), 0, -1); ?>action\/[_a-zA-Z0-9\/]+.*$/.exec(href)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -12,19 +12,19 @@ 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\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);
|
||||
Typecho_Widget::widget('Widget_Menu')->to($menu);
|
||||
\Widget\Options::alloc()->to($options);
|
||||
\Widget\User::alloc()->to($user);
|
||||
\Widget\Security::alloc()->to($security);
|
||||
\Widget\Menu::alloc()->to($menu);
|
||||
|
||||
/** 初始化上下文 */
|
||||
$request = Typecho_Request::getInstance();
|
||||
$response = Typecho_Response::getInstance();
|
||||
$request = $options->request;
|
||||
$response = $options->response;
|
||||
|
||||
/** 检测是否是第一次登录 */
|
||||
$currentMenu = $menu->getCurrentMenu();
|
||||
@ -33,22 +33,21 @@ if (!empty($currentMenu)) {
|
||||
$params = parse_url($currentMenu[2]);
|
||||
$adminFile = basename($params['path']);
|
||||
|
||||
if (!$user->logged && !Typecho_Cookie::get('__typecho_first_run')) {
|
||||
|
||||
if (!$user->logged && !\Typecho\Cookie::get('__typecho_first_run')) {
|
||||
if ('welcome.php' != $adminFile) {
|
||||
$response->redirect(Typecho_Common::url('welcome.php', $options->adminUrl));
|
||||
$response->redirect(\Typecho\Common::url('welcome.php', $options->adminUrl));
|
||||
} else {
|
||||
Typecho_Cookie::set('__typecho_first_run', 1);
|
||||
\Typecho\Cookie::set('__typecho_first_run', 1);
|
||||
}
|
||||
} elseif ($user->pass('administrator', true)) {
|
||||
/** 检测版本是否升级 */
|
||||
$mustUpgrade = version_compare(Typecho_Common::VERSION, $options->version, '>');
|
||||
$mustUpgrade = version_compare(\Typecho\Common::VERSION, $options->version, '>');
|
||||
|
||||
if ($mustUpgrade && 'upgrade.php' != $adminFile && 'backup.php' != $adminFile) {
|
||||
$response->redirect(Typecho_Common::url('upgrade.php', $options->adminUrl));
|
||||
} else if (!$mustUpgrade && 'upgrade.php' == $adminFile) {
|
||||
$response->redirect(\Typecho\Common::url('upgrade.php', $options->adminUrl));
|
||||
} elseif (!$mustUpgrade && 'upgrade.php' == $adminFile) {
|
||||
$response->redirect($options->adminUrl);
|
||||
} else if (!$mustUpgrade && 'welcome.php' == $adminFile && $user->logged) {
|
||||
} elseif (!$mustUpgrade && 'welcome.php' == $adminFile && $user->logged) {
|
||||
$response->redirect($options->adminUrl);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ a.button:hover, a.balloon-button:hover { background-color: #A5CADC; color: #FFF;
|
||||
/** Forms */
|
||||
input[type=text], input[type=password], input[type=email], textarea { background: #FFF; border: 1px solid #D9D9D6; padding: 7px; border-radius: 2px; box-sizing: border-box; }
|
||||
|
||||
input[type=text]:disabled, input[type=text]:read-only, input[type=password]:disabled, input[type=password]:read-only, input[type=email]:disabled, input[type=email]:read-only, textarea:disabled, textarea:read-only { background: #F3F3F3; }
|
||||
|
||||
textarea { resize: vertical; line-height: 1.5; }
|
||||
|
||||
input[type="radio"], input[type="checkbox"] { margin-right: 3px; }
|
||||
@ -203,9 +205,6 @@ select { border: 1px solid #CCC; height: 28px; }
|
||||
|
||||
.typecho-foot .resource a { margin: 0 3px; color: #999; }
|
||||
|
||||
/* 低版本浏览器升级提示 */
|
||||
.browsehappy { border: none; text-align: center; }
|
||||
|
||||
/** 顶部消息样式 by 70 */
|
||||
.popup { display: none; position: absolute; top: 0; left: 0; margin: 0; padding: 8px 0; border: none; width: 100%; z-index: 10; text-align: center; border-radius: 0; }
|
||||
|
||||
|
@ -1,73 +1,82 @@
|
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
|
||||
<?php if (!defined('__TYPECHO_ADMIN__')) exit; ?>
|
||||
<?php
|
||||
$fields = isset($post) ? $post->getFieldItems() : $page->getFieldItems();
|
||||
$defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaultFieldItems();
|
||||
?>
|
||||
<section id="custom-field" class="typecho-post-option<?php if (empty($defaultFields) && empty($fields)): ?> fold<?php endif; ?>">
|
||||
<label id="custom-field-expand" class="typecho-label"><a href="##"><i class="i-caret-right"></i> <?php _e('自定义字段'); ?></a></label>
|
||||
<table class="typecho-list-table mono">
|
||||
<colgroup>
|
||||
<col width="25%"/>
|
||||
<col width="10%"/>
|
||||
<col width="55%"/>
|
||||
<col width="10%"/>
|
||||
</colgroup>
|
||||
<?php foreach ($defaultFields as $field): ?>
|
||||
<?php list ($label, $input) = $field; ?>
|
||||
<tr>
|
||||
<td><?php $label->render(); ?></td>
|
||||
<td colspan="3"><?php $input->render(); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($fields as $field): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
|
||||
<input type="text" name="fieldNames[]" value="<?php echo htmlspecialchars($field['name']); ?>" id="fieldname" class="text-s w-100">
|
||||
</td>
|
||||
<td>
|
||||
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
|
||||
<select name="fieldTypes[]" id="fieldtype">
|
||||
<option value="str"<?php if ('str' == $field['type']): ?> selected<?php endif; ?>><?php _e('字符'); ?></option>
|
||||
<option value="int"<?php if ('int' == $field['type']): ?> selected<?php endif; ?>><?php _e('整数'); ?></option>
|
||||
<option value="float"<?php if ('float' == $field['type']): ?> selected<?php endif; ?>><?php _e('小数'); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
|
||||
<textarea name="fieldValues[]" id="fieldvalue" class="text-s w-100" rows="2"><?php echo htmlspecialchars($field[$field['type'] . '_value']); ?></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($defaultFields) && empty($fields)): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
|
||||
<input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" id="fieldname" class="text-s w-100">
|
||||
</td>
|
||||
<td>
|
||||
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
|
||||
<select name="fieldTypes[]" id="fieldtype">
|
||||
<option value="str"><?php _e('字符'); ?></option>
|
||||
<option value="int"><?php _e('整数'); ?></option>
|
||||
<option value="float"><?php _e('小数'); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
|
||||
<textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" id="fieldvalue" class="text-s w-100" rows="2"></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
<div class="description clearfix">
|
||||
<button type="button" class="btn btn-xs operate-add"><?php _e('+添加字段'); ?></button>
|
||||
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="http://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?>
|
||||
</div>
|
||||
</section>
|
||||
<section id="custom-field"
|
||||
class="typecho-post-option<?php if (empty($defaultFields) && empty($fields)): ?> fold<?php endif; ?>">
|
||||
<label id="custom-field-expand" class="typecho-label"><a href="##"><i
|
||||
class="i-caret-right"></i> <?php _e('自定义字段'); ?></a></label>
|
||||
<table class="typecho-list-table mono">
|
||||
<colgroup>
|
||||
<col width="25%"/>
|
||||
<col width="10%"/>
|
||||
<col width="55%"/>
|
||||
<col width="10%"/>
|
||||
</colgroup>
|
||||
<?php foreach ($defaultFields as $field): ?>
|
||||
<?php [$label, $input] = $field; ?>
|
||||
<tr>
|
||||
<td><?php $label->render(); ?></td>
|
||||
<td colspan="3"><?php $input->render(); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($fields as $field): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
|
||||
<input type="text" name="fieldNames[]" value="<?php echo htmlspecialchars($field['name']); ?>"
|
||||
id="fieldname" class="text-s w-100">
|
||||
</td>
|
||||
<td>
|
||||
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
|
||||
<select name="fieldTypes[]" id="fieldtype">
|
||||
<option
|
||||
value="str"<?php if ('str' == $field['type']): ?> selected<?php endif; ?>><?php _e('字符'); ?></option>
|
||||
<option
|
||||
value="int"<?php if ('int' == $field['type']): ?> selected<?php endif; ?>><?php _e('整数'); ?></option>
|
||||
<option
|
||||
value="float"<?php if ('float' == $field['type']): ?> selected<?php endif; ?>><?php _e('小数'); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
|
||||
<textarea name="fieldValues[]" id="fieldvalue" class="text-s w-100"
|
||||
rows="2"><?php echo htmlspecialchars($field[$field['type'] . '_value']); ?></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($defaultFields) && empty($fields)): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
|
||||
<input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" id="fieldname"
|
||||
class="text-s w-100">
|
||||
</td>
|
||||
<td>
|
||||
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
|
||||
<select name="fieldTypes[]" id="fieldtype">
|
||||
<option value="str"><?php _e('字符'); ?></option>
|
||||
<option value="int"><?php _e('整数'); ?></option>
|
||||
<option value="float"><?php _e('小数'); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
|
||||
<textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" id="fieldvalue"
|
||||
class="text-s w-100" rows="2"></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
<div class="description clearfix">
|
||||
<button type="button" class="btn btn-xs operate-add"><?php _e('+添加字段'); ?></button>
|
||||
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="http://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -109,7 +109,7 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
|
||||
<?php Typecho_Plugin::factory('admin/editor-js.php')->markdownEditor($content); ?>
|
||||
<?php \Typecho\Plugin::factory('admin/editor-js.php')->markdownEditor($content); ?>
|
||||
|
||||
var th = textarea.height(), ph = preview.height(),
|
||||
uploadBtn = $('<button type="button" id="btn-fullscreen-upload" class="btn btn-link">'
|
||||
|
@ -1,13 +1,14 @@
|
||||
<?php
|
||||
|
||||
include 'common.php';
|
||||
|
||||
$panel = $request->get('panel');
|
||||
$panelTable = unserialize($options->panelTable);
|
||||
|
||||
if (!isset($panelTable['file']) || !in_array(urlencode($panel), $panelTable['file'])) {
|
||||
throw new Typecho_Plugin_Exception(_t('页面不存在'), 404);
|
||||
throw new \Typecho\Plugin\Exception(_t('页面不存在'), 404);
|
||||
}
|
||||
|
||||
list ($pluginName, $file) = explode('/', trim($panel, '/'), 2);
|
||||
[$pluginName, $file] = explode('/', trim($panel, '/'), 2);
|
||||
|
||||
require_once $options->pluginDir($pluginName) . '/' . $panel;
|
||||
require_once $options->pluginDir($pluginName) . '/' . $file;
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
|
||||
<?php
|
||||
if (isset($post) && $post instanceof Typecho_Widget && $post->have()) {
|
||||
if (isset($post) && $post instanceof \Typecho\Widget && $post->have()) {
|
||||
$fileParentContent = $post;
|
||||
} else if (isset($page) && $page instanceof Typecho_Widget && $page->have()) {
|
||||
} elseif (isset($page) && $page instanceof \Typecho\Widget && $page->have()) {
|
||||
$fileParentContent = $page;
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,9 @@ if (isset($post) || isset($page)) {
|
||||
$cid = isset($post) ? $post->cid : $page->cid;
|
||||
|
||||
if ($cid) {
|
||||
Typecho_Widget::widget('Widget_Contents_Attachment_Related', 'parentId=' . $cid)->to($attachment);
|
||||
\Widget\Contents\Related::alloc(['parentId' => $cid])->to($attachment);
|
||||
} else {
|
||||
Typecho_Widget::widget('Widget_Contents_Attachment_Unattached')->to($attachment);
|
||||
\Widget\Contents\Attachment\Unattached::alloc()->to($attachment);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -3,4 +3,4 @@
|
||||
</html>
|
||||
<?php
|
||||
/** 注册一个结束插件 */
|
||||
Typecho_Plugin::factory('admin/footer.php')->end();
|
||||
\Typecho\Plugin::factory('admin/footer.php')->end();
|
||||
|
@ -8,7 +8,7 @@ $header = '<link rel="stylesheet" href="' . $options->adminStaticUrl('css', 'nor
|
||||
<link rel="stylesheet" href="' . $options->adminStaticUrl('css', 'style.css', true) . '">';
|
||||
|
||||
/** 注册一个初始化插件 */
|
||||
$header = Typecho_Plugin::factory('admin/header.php')->header($header);
|
||||
$header = \Typecho\Plugin::factory('admin/header.php')->header($header);
|
||||
|
||||
?><!DOCTYPE HTML>
|
||||
<html>
|
||||
@ -21,6 +21,3 @@ $header = Typecho_Plugin::factory('admin/header.php')->header($header);
|
||||
<?php echo $header; ?>
|
||||
</head>
|
||||
<body<?php if (isset($bodyClass)) {echo ' class="' . $bodyClass . '"';} ?>>
|
||||
<!--[if lt IE 9]>
|
||||
<div class="message error browsehappy" role="dialog"><?php _e('当前网页 <strong>不支持</strong> 你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>'); ?>.</div>
|
||||
<![endif]-->
|
||||
|
174
admin/index.php
174
admin/index.php
@ -3,7 +3,7 @@ include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat');
|
||||
$stat = \Widget\Stat::alloc();
|
||||
?>
|
||||
<div class="main">
|
||||
<div class="container typecho-dashboard">
|
||||
@ -11,35 +11,40 @@ $stat = Typecho_Widget::widget('Widget_Stat');
|
||||
<div class="row typecho-page-main">
|
||||
<div class="col-mb-12 welcome-board" role="main">
|
||||
<p><?php _e('目前有 <em>%s</em> 篇文章, 并有 <em>%s</em> 条关于你的评论在 <em>%s</em> 个分类中.',
|
||||
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?>
|
||||
<br><?php _e('点击下面的链接快速开始:'); ?></p>
|
||||
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?>
|
||||
<br><?php _e('点击下面的链接快速开始:'); ?></p>
|
||||
|
||||
<ul id="start-link" class="clearfix">
|
||||
<?php if($user->pass('contributor', true)): ?>
|
||||
<li><a href="<?php $options->adminUrl('write-post.php'); ?>"><?php _e('撰写新文章'); ?></a></li>
|
||||
<?php if($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->waitingCommentsNum > 0): ?>
|
||||
<li><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核的评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->waitingCommentsNum(); ?></span>
|
||||
</li>
|
||||
<?php elseif($stat->myWaitingCommentsNum > 0): ?>
|
||||
<li><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->spamCommentsNum > 0): ?>
|
||||
<li><a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->spamCommentsNum(); ?></span>
|
||||
</li>
|
||||
<?php elseif($stat->mySpamCommentsNum > 0): ?>
|
||||
<li><a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if($user->pass('administrator', true)): ?>
|
||||
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('更换外观'); ?></a></li>
|
||||
<li><a href="<?php $options->adminUrl('plugins.php'); ?>"><?php _e('插件管理'); ?></a></li>
|
||||
<li><a href="<?php $options->adminUrl('options-general.php'); ?>"><?php _e('系统设置'); ?></a></li>
|
||||
<?php endif; ?>
|
||||
<?php if ($user->pass('contributor', true)): ?>
|
||||
<li><a href="<?php $options->adminUrl('write-post.php'); ?>"><?php _e('撰写新文章'); ?></a></li>
|
||||
<?php if ($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->waitingCommentsNum > 0): ?>
|
||||
<li>
|
||||
<a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核的评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->waitingCommentsNum(); ?></span>
|
||||
</li>
|
||||
<?php elseif ($stat->myWaitingCommentsNum > 0): ?>
|
||||
<li>
|
||||
<a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if ($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->spamCommentsNum > 0): ?>
|
||||
<li>
|
||||
<a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->spamCommentsNum(); ?></span>
|
||||
</li>
|
||||
<?php elseif ($stat->mySpamCommentsNum > 0): ?>
|
||||
<li>
|
||||
<a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if ($user->pass('administrator', true)): ?>
|
||||
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('更换外观'); ?></a></li>
|
||||
<li><a href="<?php $options->adminUrl('plugins.php'); ?>"><?php _e('插件管理'); ?></a></li>
|
||||
<li><a href="<?php $options->adminUrl('options-general.php'); ?>"><?php _e('系统设置'); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<!--<li><a href="<?php $options->adminUrl('profile.php'); ?>"><?php _e('更新我的资料'); ?></a></li>-->
|
||||
</ul>
|
||||
@ -48,18 +53,18 @@ $stat = Typecho_Widget::widget('Widget_Stat');
|
||||
<div class="col-mb-12 col-tb-4" role="complementary">
|
||||
<section class="latest-link">
|
||||
<h3><?php _e('最近发布的文章'); ?></h3>
|
||||
<?php Typecho_Widget::widget('Widget_Contents_Post_Recent', 'pageSize=10')->to($posts); ?>
|
||||
<?php \Widget\Contents\Post\Recent::alloc('pageSize=10')->to($posts); ?>
|
||||
<ul>
|
||||
<?php if($posts->have()): ?>
|
||||
<?php while($posts->next()): ?>
|
||||
<li>
|
||||
<span><?php $posts->date('n.j'); ?></span>
|
||||
<a href="<?php $posts->permalink(); ?>" class="title"><?php $posts->title(); ?></a>
|
||||
</li>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<li><em><?php _e('暂时没有文章'); ?></em></li>
|
||||
<?php endif; ?>
|
||||
<?php if ($posts->have()): ?>
|
||||
<?php while ($posts->next()): ?>
|
||||
<li>
|
||||
<span><?php $posts->date('n.j'); ?></span>
|
||||
<a href="<?php $posts->permalink(); ?>" class="title"><?php $posts->title(); ?></a>
|
||||
</li>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<li><em><?php _e('暂时没有文章'); ?></em></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
@ -68,17 +73,18 @@ $stat = Typecho_Widget::widget('Widget_Stat');
|
||||
<section class="latest-link">
|
||||
<h3><?php _e('最近得到的回复'); ?></h3>
|
||||
<ul>
|
||||
<?php Typecho_Widget::widget('Widget_Comments_Recent', 'pageSize=10')->to($comments); ?>
|
||||
<?php if($comments->have()): ?>
|
||||
<?php while($comments->next()): ?>
|
||||
<li>
|
||||
<span><?php $comments->date('n.j'); ?></span>
|
||||
<a href="<?php $comments->permalink(); ?>" class="title"><?php $comments->author(false); ?></a>:
|
||||
<?php $comments->excerpt(35, '...'); ?>
|
||||
</li>
|
||||
<?php endwhile; ?>
|
||||
<?php \Widget\Comments\Recent::alloc('pageSize=10')->to($comments); ?>
|
||||
<?php if ($comments->have()): ?>
|
||||
<?php while ($comments->next()): ?>
|
||||
<li>
|
||||
<span><?php $comments->date('n.j'); ?></span>
|
||||
<a href="<?php $comments->permalink(); ?>"
|
||||
class="title"><?php $comments->author(false); ?></a>:
|
||||
<?php $comments->excerpt(35, '...'); ?>
|
||||
</li>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<li><?php _e('暂时没有回复'); ?></li>
|
||||
<li><?php _e('暂时没有回复'); ?></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</section>
|
||||
@ -104,46 +110,46 @@ include 'common-js.php';
|
||||
?>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
var ul = $('#typecho-message ul'), cache = window.sessionStorage,
|
||||
html = cache ? cache.getItem('feed') : '',
|
||||
update = cache ? cache.getItem('update') : '';
|
||||
|
||||
if (!!html) {
|
||||
ul.html(html);
|
||||
} else {
|
||||
html = '';
|
||||
$.get('<?php $options->index('/action/ajax?do=feed'); ?>', function (o) {
|
||||
for (var i = 0; i < o.length; i ++) {
|
||||
var item = o[i];
|
||||
html += '<li><span>' + item.date + '</span> <a href="' + item.link + '" target="_blank">' + item.title
|
||||
+ '</a></li>';
|
||||
}
|
||||
$(document).ready(function () {
|
||||
var ul = $('#typecho-message ul'), cache = window.sessionStorage,
|
||||
html = cache ? cache.getItem('feed') : '',
|
||||
update = cache ? cache.getItem('update') : '';
|
||||
|
||||
if (!!html) {
|
||||
ul.html(html);
|
||||
cache.setItem('feed', html);
|
||||
}, 'json');
|
||||
}
|
||||
} else {
|
||||
html = '';
|
||||
$.get('<?php $options->index('/action/ajax?do=feed'); ?>', function (o) {
|
||||
for (var i = 0; i < o.length; i++) {
|
||||
var item = o[i];
|
||||
html += '<li><span>' + item.date + '</span> <a href="' + item.link + '" target="_blank">' + item.title
|
||||
+ '</a></li>';
|
||||
}
|
||||
|
||||
function applyUpdate(update) {
|
||||
if (update.available) {
|
||||
$('<div class="update-check message error"><p>'
|
||||
+ '<?php _e('您当前使用的版本是 %s'); ?>'.replace('%s', update.current) + '<br />'
|
||||
+ '<strong><a href="' + update.link + '" target="_blank">'
|
||||
+ '<?php _e('官方最新版本是 %s'); ?>'.replace('%s', update.latest) + '</a></strong></p></div>')
|
||||
.insertAfter('.typecho-page-title').effect('highlight');
|
||||
ul.html(html);
|
||||
cache.setItem('feed', html);
|
||||
}, 'json');
|
||||
}
|
||||
}
|
||||
|
||||
if (!!update) {
|
||||
applyUpdate($.parseJSON(update));
|
||||
} else {
|
||||
$.get('<?php $options->index('/action/ajax?do=checkVersion'); ?>', function (o, status, resp) {
|
||||
applyUpdate(o);
|
||||
cache.setItem('update', resp.responseText);
|
||||
}, 'json');
|
||||
}
|
||||
});
|
||||
function applyUpdate(update) {
|
||||
if (update.available) {
|
||||
$('<div class="update-check message error"><p>'
|
||||
+ '<?php _e('您当前使用的版本是 %s'); ?>'.replace('%s', update.current) + '<br />'
|
||||
+ '<strong><a href="' + update.link + '" target="_blank">'
|
||||
+ '<?php _e('官方最新版本是 %s'); ?>'.replace('%s', update.latest) + '</a></strong></p></div>')
|
||||
.insertAfter('.typecho-page-title').effect('highlight');
|
||||
}
|
||||
}
|
||||
|
||||
if (!!update) {
|
||||
applyUpdate($.parseJSON(update));
|
||||
} else {
|
||||
$.get('<?php $options->index('/action/ajax?do=checkVersion'); ?>', function (o, status, resp) {
|
||||
applyUpdate(o);
|
||||
cache.setItem('update', resp.responseText);
|
||||
}, 'json');
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
<?php include 'footer.php'; ?>
|
||||
|
@ -4,8 +4,8 @@ include 'common.php';
|
||||
if ($user->hasLogin()) {
|
||||
$response->redirect($options->adminUrl);
|
||||
}
|
||||
$rememberName = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_name'));
|
||||
Typecho_Cookie::delete('__typecho_remember_name');
|
||||
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name'));
|
||||
\Typecho\Cookie::delete('__typecho_remember_name');
|
||||
|
||||
$bodyClass = 'body-100';
|
||||
|
||||
|
@ -3,27 +3,35 @@ include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
Typecho_Widget::widget('Widget_Metas_Category_Admin')->to($categories);
|
||||
\Widget\Metas\Category\Admin::alloc()->to($categories);
|
||||
?>
|
||||
|
||||
<div class="main">
|
||||
<div class="body container">
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main manage-metas">
|
||||
|
||||
<div class="col-mb-12" role="main">
|
||||
|
||||
<form method="post" name="manage_categories" class="operate-form">
|
||||
|
||||
<div class="col-mb-12" role="main">
|
||||
|
||||
<form method="post" name="manage_categories" class="operate-form">
|
||||
<div class="typecho-list-operate clearfix">
|
||||
<div class="operate">
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
|
||||
class="typecho-table-select-all"/></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i
|
||||
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('此分类下的所有内容将被删除, 你确认要删除这些分类吗?'); ?>" href="<?php $security->index('/action/metas-category-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
<li><a lang="<?php _e('刷新分类可能需要等待较长时间, 你确认要刷新这些分类吗?'); ?>" href="<?php $security->index('/action/metas-category-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a></li>
|
||||
<li><a lang="<?php _e('此分类下的所有内容将被删除, 你确认要删除这些分类吗?'); ?>"
|
||||
href="<?php $security->index('/action/metas-category-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
|
||||
</li>
|
||||
<li><a lang="<?php _e('刷新分类可能需要等待较长时间, 你确认要刷新这些分类吗?'); ?>"
|
||||
href="<?php $security->index('/action/metas-category-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a>
|
||||
</li>
|
||||
<li class="multiline">
|
||||
<button type="button" class="btn merge btn-s" rel="<?php $security->index('/action/metas-category-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
|
||||
<button type="button" class="btn merge btn-s"
|
||||
rel="<?php $security->index('/action/metas-category-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
|
||||
<select name="merge">
|
||||
<?php $categories->parse('<option value="{mid}">{name}</option>'); ?>
|
||||
</select>
|
||||
@ -47,53 +55,63 @@ Typecho_Widget::widget('Widget_Metas_Category_Admin')->to($categories);
|
||||
<col width="10%" class="kit-hidden-mb"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="nodrag">
|
||||
<th class="kit-hidden-mb"> </th>
|
||||
<th><?php _e('名称'); ?></th>
|
||||
<th><?php _e('子分类'); ?></th>
|
||||
<th class="kit-hidden-mb"><?php _e('缩略名'); ?></th>
|
||||
<th> </th>
|
||||
<th class="kit-hidden-mb"><?php _e('文章数'); ?></th>
|
||||
</tr>
|
||||
<tr class="nodrag">
|
||||
<th class="kit-hidden-mb"></th>
|
||||
<th><?php _e('名称'); ?></th>
|
||||
<th><?php _e('子分类'); ?></th>
|
||||
<th class="kit-hidden-mb"><?php _e('缩略名'); ?></th>
|
||||
<th></th>
|
||||
<th class="kit-hidden-mb"><?php _e('文章数'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if($categories->have()): ?>
|
||||
<?php if ($categories->have()): ?>
|
||||
<?php while ($categories->next()): ?>
|
||||
<tr id="mid-<?php $categories->theId(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $categories->mid(); ?>" name="mid[]"/></td>
|
||||
<td><a href="<?php $options->adminUrl('category.php?mid=' . $categories->mid); ?>"><?php $categories->name(); ?></a>
|
||||
<a href="<?php $categories->permalink(); ?>" title="<?php _e('浏览 %s', $categories->name); ?>"><i class="i-exlink"></i></a>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<?php if (count($categories->children) > 0): ?>
|
||||
<a href="<?php $options->adminUrl('manage-categories.php?parent=' . $categories->mid); ?>"><?php echo _n('一个分类', '%d个分类', count($categories->children)); ?></a>
|
||||
<?php else: ?>
|
||||
<a href="<?php $options->adminUrl('category.php?parent=' . $categories->mid); ?>"><?php echo _e('新增'); ?></a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><?php $categories->slug(); ?></td>
|
||||
<td>
|
||||
<?php if ($options->defaultCategory == $categories->mid): ?>
|
||||
<?php _e('默认'); ?>
|
||||
<?php else: ?>
|
||||
<a class="hidden-by-mouse" href="<?php $security->index('/action/metas-category-edit?do=default&mid=' . $categories->mid); ?>" title="<?php _e('设为默认'); ?>"><?php _e('默认'); ?></a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><a class="balloon-button left size-<?php echo Typecho_Common::splitByCount($categories->count, 1, 10, 20, 50, 100); ?>" href="<?php $options->adminUrl('manage-posts.php?category=' . $categories->mid); ?>"><?php $categories->count(); ?></a></td>
|
||||
</tr>
|
||||
<tr id="mid-<?php $categories->theId(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox"
|
||||
value="<?php $categories->mid(); ?>"
|
||||
name="mid[]"/></td>
|
||||
<td>
|
||||
<a href="<?php $options->adminUrl('category.php?mid=' . $categories->mid); ?>"><?php $categories->name(); ?></a>
|
||||
<a href="<?php $categories->permalink(); ?>"
|
||||
title="<?php _e('浏览 %s', $categories->name); ?>"><i class="i-exlink"></i></a>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<?php if (count($categories->children) > 0): ?>
|
||||
<a href="<?php $options->adminUrl('manage-categories.php?parent=' . $categories->mid); ?>"><?php echo _n('一个分类', '%d个分类', count($categories->children)); ?></a>
|
||||
<?php else: ?>
|
||||
<a href="<?php $options->adminUrl('category.php?parent=' . $categories->mid); ?>"><?php echo _e('新增'); ?></a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><?php $categories->slug(); ?></td>
|
||||
<td>
|
||||
<?php if ($options->defaultCategory == $categories->mid): ?>
|
||||
<?php _e('默认'); ?>
|
||||
<?php else: ?>
|
||||
<a class="hidden-by-mouse"
|
||||
href="<?php $security->index('/action/metas-category-edit?do=default&mid=' . $categories->mid); ?>"
|
||||
title="<?php _e('设为默认'); ?>"><?php _e('默认'); ?></a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><a
|
||||
class="balloon-button left size-<?php echo \Typecho\Common::splitByCount($categories->count, 1, 10, 20, 50, 100); ?>"
|
||||
href="<?php $options->adminUrl('manage-posts.php?category=' . $categories->mid); ?>"><?php $categories->count(); ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何分类'); ?></h6></td>
|
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何分类'); ?></h6>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -104,51 +122,51 @@ include 'common-js.php';
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
$(document).ready(function () {
|
||||
var table = $('.typecho-list-table').tableDnD({
|
||||
onDrop : function () {
|
||||
var ids = [];
|
||||
(function () {
|
||||
$(document).ready(function () {
|
||||
var table = $('.typecho-list-table').tableDnD({
|
||||
onDrop: function () {
|
||||
var ids = [];
|
||||
|
||||
$('input[type=checkbox]', table).each(function () {
|
||||
ids.push($(this).val());
|
||||
});
|
||||
$('input[type=checkbox]', table).each(function () {
|
||||
ids.push($(this).val());
|
||||
});
|
||||
|
||||
$.post('<?php $security->index('/action/metas-category-edit?do=sort'); ?>',
|
||||
$.param({mid : ids}));
|
||||
$.post('<?php $security->index('/action/metas-category-edit?do=sort'); ?>',
|
||||
$.param({mid: ids}));
|
||||
|
||||
$('tr', table).each(function (i) {
|
||||
if (i % 2) {
|
||||
$(this).addClass('even');
|
||||
} else {
|
||||
$(this).removeClass('even');
|
||||
}
|
||||
});
|
||||
}
|
||||
$('tr', table).each(function (i) {
|
||||
if (i % 2) {
|
||||
$(this).addClass('even');
|
||||
} else {
|
||||
$(this).removeClass('even');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
table.tableSelectable({
|
||||
checkEl: 'input[type=checkbox]',
|
||||
rowEl: 'tr',
|
||||
selectAllEl: '.typecho-table-select-all',
|
||||
actionEl: '.dropdown-menu a'
|
||||
});
|
||||
|
||||
$('.btn-drop').dropdownMenu({
|
||||
btnEl: '.dropdown-toggle',
|
||||
menuEl: '.dropdown-menu'
|
||||
});
|
||||
|
||||
$('.dropdown-menu button.merge').click(function () {
|
||||
var btn = $(this);
|
||||
btn.parents('form').attr('action', btn.attr('rel')).submit();
|
||||
});
|
||||
|
||||
<?php if (isset($request->mid)): ?>
|
||||
$('.typecho-mini-panel').effect('highlight', '#AACB36');
|
||||
<?php endif; ?>
|
||||
});
|
||||
|
||||
table.tableSelectable({
|
||||
checkEl : 'input[type=checkbox]',
|
||||
rowEl : 'tr',
|
||||
selectAllEl : '.typecho-table-select-all',
|
||||
actionEl : '.dropdown-menu a'
|
||||
});
|
||||
|
||||
$('.btn-drop').dropdownMenu({
|
||||
btnEl : '.dropdown-toggle',
|
||||
menuEl : '.dropdown-menu'
|
||||
});
|
||||
|
||||
$('.dropdown-menu button.merge').click(function () {
|
||||
var btn = $(this);
|
||||
btn.parents('form').attr('action', btn.attr('rel')).submit();
|
||||
});
|
||||
|
||||
<?php if (isset($request->mid)): ?>
|
||||
$('.typecho-mini-panel').effect('highlight', '#AACB36');
|
||||
<?php endif; ?>
|
||||
});
|
||||
})();
|
||||
})();
|
||||
</script>
|
||||
<?php include 'footer.php'; ?>
|
||||
|
||||
|
@ -3,9 +3,9 @@ include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat');
|
||||
$comments = Typecho_Widget::widget('Widget_Comments_Admin');
|
||||
$isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typecho_Cookie::get('__typecho_all_comments'));
|
||||
$stat = \Widget\Stat::alloc();
|
||||
$comments = \Widget\Comments\Admin::alloc();
|
||||
$isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Typecho\Cookie::get('__typecho_all_comments'));
|
||||
?>
|
||||
<div class="main">
|
||||
<div class="body container">
|
||||
@ -112,7 +112,7 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typ
|
||||
'text' => $comments->text
|
||||
);
|
||||
|
||||
echo htmlspecialchars(Json::encode($comment));
|
||||
echo htmlspecialchars(json_encode($comment));
|
||||
?>">
|
||||
<td valign="top" class="kit-hidden-mb">
|
||||
<input type="checkbox" value="<?php $comments->coid(); ?>" name="coid[]"/>
|
||||
|
@ -3,112 +3,134 @@ include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat');
|
||||
$stat = \Widget\Stat::alloc();
|
||||
$attachments = \Widget\Contents\Attachment\Admin::alloc();
|
||||
?>
|
||||
|
||||
<?php Typecho_Widget::widget('Widget_Contents_Attachment_Admin')->to($attachments); ?>
|
||||
<div class="main">
|
||||
<div class="body container">
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main" role="main">
|
||||
<div class="col-mb-12">
|
||||
|
||||
|
||||
<div class="typecho-list-operate clearfix">
|
||||
<form method="get">
|
||||
<div class="operate">
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
|
||||
class="typecho-table-select-all"/></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>" href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul>
|
||||
<button class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>" lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i
|
||||
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>"
|
||||
href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="btn btn-s btn-warn btn-operate"
|
||||
href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>"
|
||||
lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search" role="search">
|
||||
<?php if ('' != $request->keywords): ?>
|
||||
<a href="<?php $options->adminUrl('manage-medias.php'); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<a href="<?php $options->adminUrl('manage-medias.php'); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<?php endif; ?>
|
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
|
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
|
||||
value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
|
||||
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div><!-- end .typecho-list-operate -->
|
||||
|
||||
|
||||
<form method="post" name="manage_medias" class="operate-form">
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table draggable">
|
||||
<colgroup>
|
||||
<col width="20" class="kit-hidden-mb"/>
|
||||
<col width="6%" class="kit-hidden-mb"/>
|
||||
<col width="30%"/>
|
||||
<col width="" class="kit-hidden-mb"/>
|
||||
<col width="30%" class="kit-hidden-mb"/>
|
||||
<col width="16%"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table draggable">
|
||||
<colgroup>
|
||||
<col width="20" class="kit-hidden-mb"/>
|
||||
<col width="6%" class="kit-hidden-mb"/>
|
||||
<col width="30%"/>
|
||||
<col width="" class="kit-hidden-mb"/>
|
||||
<col width="30%" class="kit-hidden-mb"/>
|
||||
<col width="16%"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="kit-hidden-mb"> </th>
|
||||
<th class="kit-hidden-mb"> </th>
|
||||
<th class="kit-hidden-mb"></th>
|
||||
<th class="kit-hidden-mb"></th>
|
||||
<th><?php _e('文件名'); ?></th>
|
||||
<th class="kit-hidden-mb"><?php _e('上传者'); ?></th>
|
||||
<th class="kit-hidden-mb"><?php _e('所属文章'); ?></th>
|
||||
<th><?php _e('发布日期'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if($attachments->have()): ?>
|
||||
<?php while($attachments->next()): ?>
|
||||
<?php $mime = Typecho_Common::mimeIconType($attachments->attachment->mime); ?>
|
||||
<tr id="<?php $attachments->theId(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $attachments->cid(); ?>" name="cid[]"/></td>
|
||||
<td class="kit-hidden-mb"><a href="<?php $options->adminUrl('manage-comments.php?cid=' . $attachments->cid); ?>" class="balloon-button size-<?php echo Typecho_Common::splitByCount($attachments->commentsNum, 1, 10, 20, 50, 100); ?>"><?php $attachments->commentsNum(); ?></a></td>
|
||||
<td>
|
||||
<i class="mime-<?php echo $mime; ?>"></i>
|
||||
<a href="<?php $options->adminUrl('media.php?cid=' . $attachments->cid); ?>"><?php $attachments->title(); ?></a>
|
||||
<a href="<?php $attachments->permalink(); ?>" title="<?php _e('浏览 %s', $attachments->title); ?>"><i class="i-exlink"></i></a>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><?php $attachments->author(); ?></td>
|
||||
<td class="kit-hidden-mb">
|
||||
<?php if ($attachments->parentPost->cid): ?>
|
||||
<a href="<?php $options->adminUrl('write-' . (0 === strpos($attachments->parentPost->type, 'post') ? 'post' : 'page') . '.php?cid=' . $attachments->parentPost->cid); ?>"><?php $attachments->parentPost->title(); ?></a>
|
||||
<?php else: ?>
|
||||
<span class="description"><?php _e('未归档'); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php $attachments->dateWord(); ?></td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if ($attachments->have()): ?>
|
||||
<?php while ($attachments->next()): ?>
|
||||
<?php $mime = \Typecho\Common::mimeIconType($attachments->attachment->mime); ?>
|
||||
<tr id="<?php $attachments->theId(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox"
|
||||
value="<?php $attachments->cid(); ?>"
|
||||
name="cid[]"/></td>
|
||||
<td class="kit-hidden-mb"><a
|
||||
href="<?php $options->adminUrl('manage-comments.php?cid=' . $attachments->cid); ?>"
|
||||
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($attachments->commentsNum, 1, 10, 20, 50, 100); ?>"><?php $attachments->commentsNum(); ?></a>
|
||||
</td>
|
||||
<td>
|
||||
<i class="mime-<?php echo $mime; ?>"></i>
|
||||
<a href="<?php $options->adminUrl('media.php?cid=' . $attachments->cid); ?>"><?php $attachments->title(); ?></a>
|
||||
<a href="<?php $attachments->permalink(); ?>"
|
||||
title="<?php _e('浏览 %s', $attachments->title); ?>"><i
|
||||
class="i-exlink"></i></a>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><?php $attachments->author(); ?></td>
|
||||
<td class="kit-hidden-mb">
|
||||
<?php if ($attachments->parentPost->cid): ?>
|
||||
<a href="<?php $options->adminUrl('write-' . (0 === strpos($attachments->parentPost->type, 'post') ? 'post' : 'page') . '.php?cid=' . $attachments->parentPost->cid); ?>"><?php $attachments->parentPost->title(); ?></a>
|
||||
<?php else: ?>
|
||||
<span class="description"><?php _e('未归档'); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php $attachments->dateWord(); ?></td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文件'); ?></h6></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文件'); ?></h6>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table><!-- end .typecho-list-table -->
|
||||
</div><!-- end .typecho-table-wrap -->
|
||||
</tbody>
|
||||
</table><!-- end .typecho-list-table -->
|
||||
</div><!-- end .typecho-table-wrap -->
|
||||
</form><!-- end .operate-form -->
|
||||
|
||||
<div class="typecho-list-operate clearfix">
|
||||
<form method="get">
|
||||
<div class="operate">
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
|
||||
class="typecho-table-select-all"/></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i
|
||||
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>" href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>"
|
||||
href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>" lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
|
||||
<button class="btn btn-s btn-warn btn-operate"
|
||||
href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>"
|
||||
lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
|
||||
</div>
|
||||
<?php if($attachments->have()): ?>
|
||||
<ul class="typecho-pager">
|
||||
<?php $attachments->pageNav(); ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
<?php if ($attachments->have()): ?>
|
||||
<ul class="typecho-pager">
|
||||
<?php $attachments->pageNav(); ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</div><!-- end .typecho-list-operate -->
|
||||
|
||||
|
||||
</div>
|
||||
</div><!-- end .typecho-page-main -->
|
||||
</div>
|
||||
|
@ -3,7 +3,8 @@ include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat');
|
||||
$stat = \Widget\Stat::alloc();
|
||||
$pages = \Widget\Contents\Page\Admin::alloc();
|
||||
?>
|
||||
<div class="main">
|
||||
<div class="body container">
|
||||
@ -13,93 +14,112 @@ $stat = Typecho_Widget::widget('Widget_Stat');
|
||||
<div class="typecho-list-operate clearfix">
|
||||
<form method="get">
|
||||
<div class="operate">
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
|
||||
class="typecho-table-select-all"/></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些页面吗?'); ?>" href="<?php $security->index('/action/contents-page-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/contents-page-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/contents-page-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a></li>
|
||||
</ul>
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i
|
||||
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些页面吗?'); ?>"
|
||||
href="<?php $security->index('/action/contents-page-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-page-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-page-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search" role="search">
|
||||
<?php if ('' != $request->keywords): ?>
|
||||
<a href="<?php $options->adminUrl('manage-pages.php'); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<a href="<?php $options->adminUrl('manage-pages.php'); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<?php endif; ?>
|
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords" />
|
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
|
||||
value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords"/>
|
||||
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div><!-- end .typecho-list-operate -->
|
||||
|
||||
|
||||
<form method="post" name="manage_pages" class="operate-form">
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table">
|
||||
<colgroup>
|
||||
<col width="20" class="kit-hidden-mb"/>
|
||||
<col width="6%" class="kit-hidden-mb"/>
|
||||
<col width="30%"/>
|
||||
<col width="30%"/>
|
||||
<col width="" class="kit-hidden-mb"/>
|
||||
<col width="16%"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table">
|
||||
<colgroup>
|
||||
<col width="20" class="kit-hidden-mb"/>
|
||||
<col width="6%" class="kit-hidden-mb"/>
|
||||
<col width="30%"/>
|
||||
<col width="30%"/>
|
||||
<col width="" class="kit-hidden-mb"/>
|
||||
<col width="16%"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="nodrag">
|
||||
<th class="kit-hidden-mb"> </th>
|
||||
<th class="kit-hidden-mb"> </th>
|
||||
<th class="kit-hidden-mb"></th>
|
||||
<th class="kit-hidden-mb"></th>
|
||||
<th><?php _e('标题'); ?></th>
|
||||
<th><?php _e('缩略名'); ?></th>
|
||||
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
|
||||
<th><?php _e('日期'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php Typecho_Widget::widget('Widget_Contents_Page_Admin')->to($pages); ?>
|
||||
<?php if($pages->have()): ?>
|
||||
<?php while($pages->next()): ?>
|
||||
<tr id="<?php $pages->theId(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $pages->cid(); ?>" name="cid[]"/></td>
|
||||
<td class="kit-hidden-mb"><a href="<?php $options->adminUrl('manage-comments.php?cid=' . $pages->cid); ?>" class="balloon-button size-<?php echo Typecho_Common::splitByCount($pages->commentsNum, 1, 10, 20, 50, 100); ?>" title="<?php $pages->commentsNum(); ?> <?php _e('评论'); ?>"><?php $pages->commentsNum(); ?></a></td>
|
||||
<td>
|
||||
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"><?php $pages->title(); ?></a>
|
||||
<?php
|
||||
if ($pages->hasSaved || 'page_draft' == $pages->type) {
|
||||
echo '<em class="status">' . _t('草稿') . '</em>';
|
||||
}
|
||||
|
||||
if ('hidden' == $pages->status) {
|
||||
echo '<em class="status">' . _t('隐藏') . '</em>';
|
||||
}
|
||||
?>
|
||||
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>" title="<?php _e('编辑 %s', htmlspecialchars($pages->title)); ?>"><i class="i-edit"></i></a>
|
||||
<?php if ('page_draft' != $pages->type): ?>
|
||||
<a href="<?php $pages->permalink(); ?>" title="<?php _e('浏览 %s', htmlspecialchars($pages->title)); ?>"><i class="i-exlink"></i></a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php $pages->slug(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php $pages->author(); ?></td>
|
||||
<td>
|
||||
<?php if ($pages->hasSaved): ?>
|
||||
<span class="description">
|
||||
<?php $modifyDate = new Typecho_Date($pages->modified); ?>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if ($pages->have()): ?>
|
||||
<?php while ($pages->next()): ?>
|
||||
<tr id="<?php $pages->theId(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $pages->cid(); ?>"
|
||||
name="cid[]"/></td>
|
||||
<td class="kit-hidden-mb"><a
|
||||
href="<?php $options->adminUrl('manage-comments.php?cid=' . $pages->cid); ?>"
|
||||
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($pages->commentsNum, 1, 10, 20, 50, 100); ?>"
|
||||
title="<?php $pages->commentsNum(); ?> <?php _e('评论'); ?>"><?php $pages->commentsNum(); ?></a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"><?php $pages->title(); ?></a>
|
||||
<?php
|
||||
if ($pages->hasSaved || 'page_draft' == $pages->type) {
|
||||
echo '<em class="status">' . _t('草稿') . '</em>';
|
||||
}
|
||||
|
||||
if ('hidden' == $pages->status) {
|
||||
echo '<em class="status">' . _t('隐藏') . '</em>';
|
||||
}
|
||||
?>
|
||||
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"
|
||||
title="<?php _e('编辑 %s', htmlspecialchars($pages->title)); ?>"><i
|
||||
class="i-edit"></i></a>
|
||||
<?php if ('page_draft' != $pages->type): ?>
|
||||
<a href="<?php $pages->permalink(); ?>"
|
||||
title="<?php _e('浏览 %s', htmlspecialchars($pages->title)); ?>"><i
|
||||
class="i-exlink"></i></a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php $pages->slug(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php $pages->author(); ?></td>
|
||||
<td>
|
||||
<?php if ($pages->hasSaved): ?>
|
||||
<span class="description">
|
||||
<?php $modifyDate = new \Typecho\Date($pages->modified); ?>
|
||||
<?php _e('保存于 %s', $modifyDate->word()); ?>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<?php $pages->dateWord(); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<?php $pages->dateWord(); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何页面'); ?></h6></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何页面'); ?></h6>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div><!-- end .typecho-table-wrap -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div><!-- end .typecho-table-wrap -->
|
||||
</form><!-- end .operate-form -->
|
||||
</div><!-- end .typecho-list -->
|
||||
</div><!-- end .typecho-page-main -->
|
||||
@ -112,25 +132,25 @@ include 'common-js.php';
|
||||
include 'table-js.php';
|
||||
?>
|
||||
|
||||
<?php if(!isset($request->status) || 'publish' == $request->get('status')): ?>
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
$(document).ready(function () {
|
||||
var table = $('.typecho-list-table').tableDnD({
|
||||
onDrop : function () {
|
||||
var ids = [];
|
||||
<?php if (!isset($request->status) || 'publish' == $request->get('status')): ?>
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
$(document).ready(function () {
|
||||
var table = $('.typecho-list-table').tableDnD({
|
||||
onDrop: function () {
|
||||
var ids = [];
|
||||
|
||||
$('input[type=checkbox]', table).each(function () {
|
||||
ids.push($(this).val());
|
||||
$('input[type=checkbox]', table).each(function () {
|
||||
ids.push($(this).val());
|
||||
});
|
||||
|
||||
$.post('<?php $security->index('/action/contents-page-edit?do=sort'); ?>',
|
||||
$.param({cid: ids}));
|
||||
}
|
||||
});
|
||||
|
||||
$.post('<?php $security->index('/action/contents-page-edit?do=sort'); ?>',
|
||||
$.param({cid : ids}));
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
|
@ -3,9 +3,9 @@ include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat');
|
||||
$posts = Typecho_Widget::widget('Widget_Contents_Post_Admin');
|
||||
$isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == Typecho_Cookie::get('__typecho_all_posts'));
|
||||
$stat = \Widget\Stat::alloc();
|
||||
$posts = \Widget\Contents\Post\Admin::alloc();
|
||||
$isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\Cookie::get('__typecho_all_posts'));
|
||||
?>
|
||||
<div class="main">
|
||||
<div class="body container">
|
||||
@ -14,183 +14,234 @@ $isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == Typecho_C
|
||||
<div class="col-mb-12 typecho-list">
|
||||
<div class="clearfix">
|
||||
<ul class="typecho-option-tabs right">
|
||||
<?php if($user->pass('editor', true) && !isset($request->uid)): ?>
|
||||
<li class="<?php if($isAllPosts): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_posts=on'); ?>"><?php _e('所有'); ?></a></li>
|
||||
<li class="<?php if(!$isAllPosts): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_posts=off'); ?>"><?php _e('我的'); ?></a></li>
|
||||
<?php endif; ?>
|
||||
<?php if ($user->pass('editor', true) && !isset($request->uid)): ?>
|
||||
<li class="<?php if ($isAllPosts): ?> current<?php endif; ?>"><a
|
||||
href="<?php echo $request->makeUriByRequest('__typecho_all_posts=on'); ?>"><?php _e('所有'); ?></a>
|
||||
</li>
|
||||
<li class="<?php if (!$isAllPosts): ?> current<?php endif; ?>"><a
|
||||
href="<?php echo $request->makeUriByRequest('__typecho_all_posts=off'); ?>"><?php _e('我的'); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
<ul class="typecho-option-tabs">
|
||||
<li<?php if(!isset($request->status) || 'all' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-posts.php'
|
||||
. (isset($request->uid) ? '?uid=' . $request->uid : '')); ?>"><?php _e('可用'); ?></a></li>
|
||||
<li<?php if('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-posts.php?status=waiting'
|
||||
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('待审核'); ?>
|
||||
<?php if(!$isAllPosts && $stat->myWaitingPostsNum > 0 && !isset($request->uid)): ?>
|
||||
<span class="balloon"><?php $stat->myWaitingPostsNum(); ?></span>
|
||||
<?php elseif($isAllPosts && $stat->waitingPostsNum > 0 && !isset($request->uid)): ?>
|
||||
<span class="balloon"><?php $stat->waitingPostsNum(); ?></span>
|
||||
<?php elseif(isset($request->uid) && $stat->currentWaitingPostsNum > 0): ?>
|
||||
<span class="balloon"><?php $stat->currentWaitingPostsNum(); ?></span>
|
||||
<?php endif; ?>
|
||||
</a></li>
|
||||
<li<?php if('draft' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-posts.php?status=draft'
|
||||
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('草稿'); ?>
|
||||
<?php if(!$isAllPosts && $stat->myDraftPostsNum > 0 && !isset($request->uid)): ?>
|
||||
<span class="balloon"><?php $stat->myDraftPostsNum(); ?></span>
|
||||
<?php elseif($isAllPosts && $stat->draftPostsNum > 0 && !isset($request->uid)): ?>
|
||||
<span class="balloon"><?php $stat->draftPostsNum(); ?></span>
|
||||
<?php elseif(isset($request->uid) && $stat->currentDraftPostsNum > 0): ?>
|
||||
<span class="balloon"><?php $stat->currentDraftPostsNum(); ?></span>
|
||||
<?php endif; ?>
|
||||
</a></li>
|
||||
<li<?php if (!isset($request->status) || 'all' == $request->get('status')): ?> class="current"<?php endif; ?>>
|
||||
<a href="<?php $options->adminUrl('manage-posts.php'
|
||||
. (isset($request->uid) ? '?uid=' . $request->uid : '')); ?>"><?php _e('可用'); ?></a>
|
||||
</li>
|
||||
<li<?php if ('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a
|
||||
href="<?php $options->adminUrl('manage-posts.php?status=waiting'
|
||||
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('待审核'); ?>
|
||||
<?php if (!$isAllPosts && $stat->myWaitingPostsNum > 0 && !isset($request->uid)): ?>
|
||||
<span class="balloon"><?php $stat->myWaitingPostsNum(); ?></span>
|
||||
<?php elseif ($isAllPosts && $stat->waitingPostsNum > 0 && !isset($request->uid)): ?>
|
||||
<span class="balloon"><?php $stat->waitingPostsNum(); ?></span>
|
||||
<?php elseif (isset($request->uid) && $stat->currentWaitingPostsNum > 0): ?>
|
||||
<span class="balloon"><?php $stat->currentWaitingPostsNum(); ?></span>
|
||||
<?php endif; ?>
|
||||
</a></li>
|
||||
<li<?php if ('draft' == $request->get('status')): ?> class="current"<?php endif; ?>><a
|
||||
href="<?php $options->adminUrl('manage-posts.php?status=draft'
|
||||
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('草稿'); ?>
|
||||
<?php if (!$isAllPosts && $stat->myDraftPostsNum > 0 && !isset($request->uid)): ?>
|
||||
<span class="balloon"><?php $stat->myDraftPostsNum(); ?></span>
|
||||
<?php elseif ($isAllPosts && $stat->draftPostsNum > 0 && !isset($request->uid)): ?>
|
||||
<span class="balloon"><?php $stat->draftPostsNum(); ?></span>
|
||||
<?php elseif (isset($request->uid) && $stat->currentDraftPostsNum > 0): ?>
|
||||
<span class="balloon"><?php $stat->currentDraftPostsNum(); ?></span>
|
||||
<?php endif; ?>
|
||||
</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="typecho-list-operate clearfix">
|
||||
<form method="get">
|
||||
<div class="operate">
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
|
||||
class="typecho-table-select-all"/></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i
|
||||
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>" href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>"
|
||||
href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
|
||||
</li>
|
||||
<?php if ($user->pass('editor', true)): ?>
|
||||
<li><a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a></li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search" role="search">
|
||||
<?php if ('' != $request->keywords || '' != $request->category): ?>
|
||||
<a href="<?php $options->adminUrl('manage-posts.php'
|
||||
. (isset($request->status) || isset($request->uid) ? '?' .
|
||||
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') .
|
||||
(isset($request->uid) ? '?uid=' . htmlspecialchars($request->get('uid')) : '') : '')); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<a href="<?php $options->adminUrl('manage-posts.php'
|
||||
. (isset($request->status) || isset($request->uid) ? '?' .
|
||||
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') .
|
||||
(isset($request->uid) ? '?uid=' . htmlspecialchars($request->get('uid')) : '') : '')); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<?php endif; ?>
|
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords" />
|
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
|
||||
value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords"/>
|
||||
<select name="category">
|
||||
<option value=""><?php _e('所有分类'); ?></option>
|
||||
<?php Typecho_Widget::widget('Widget_Metas_Category_List')->to($category); ?>
|
||||
<?php while($category->next()): ?>
|
||||
<option value="<?php $category->mid(); ?>"<?php if($request->get('category') == $category->mid): ?> selected="true"<?php endif; ?>><?php $category->name(); ?></option>
|
||||
<?php endwhile; ?>
|
||||
<option value=""><?php _e('所有分类'); ?></option>
|
||||
<?php \Widget\Metas\Category\Rows::alloc()->to($category); ?>
|
||||
<?php while ($category->next()): ?>
|
||||
<option
|
||||
value="<?php $category->mid(); ?>"<?php if ($request->get('category') == $category->mid): ?> selected="true"<?php endif; ?>><?php $category->name(); ?></option>
|
||||
<?php endwhile; ?>
|
||||
</select>
|
||||
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
|
||||
<?php if(isset($request->uid)): ?>
|
||||
<input type="hidden" value="<?php echo htmlspecialchars($request->get('uid')); ?>" name="uid" />
|
||||
<?php if (isset($request->uid)): ?>
|
||||
<input type="hidden" value="<?php echo htmlspecialchars($request->get('uid')); ?>"
|
||||
name="uid"/>
|
||||
<?php endif; ?>
|
||||
<?php if(isset($request->status)): ?>
|
||||
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>" name="status" />
|
||||
<?php if (isset($request->status)): ?>
|
||||
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>"
|
||||
name="status"/>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</form>
|
||||
</div><!-- end .typecho-list-operate -->
|
||||
|
||||
|
||||
<form method="post" name="manage_posts" class="operate-form">
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table">
|
||||
<colgroup>
|
||||
<col width="20" class="kit-hidden-mb"/>
|
||||
<col width="6%" class="kit-hidden-mb"/>
|
||||
<col width="45%"/>
|
||||
<col width="" class="kit-hidden-mb"/>
|
||||
<col width="18%" class="kit-hidden-mb"/>
|
||||
<col width="16%"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table">
|
||||
<colgroup>
|
||||
<col width="20" class="kit-hidden-mb"/>
|
||||
<col width="6%" class="kit-hidden-mb"/>
|
||||
<col width="45%"/>
|
||||
<col width="" class="kit-hidden-mb"/>
|
||||
<col width="18%" class="kit-hidden-mb"/>
|
||||
<col width="16%"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="kit-hidden-mb"> </th>
|
||||
<th class="kit-hidden-mb"> </th>
|
||||
<th class="kit-hidden-mb"></th>
|
||||
<th class="kit-hidden-mb"></th>
|
||||
<th><?php _e('标题'); ?></th>
|
||||
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
|
||||
<th class="kit-hidden-mb"><?php _e('分类'); ?></th>
|
||||
<th><?php _e('日期'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if($posts->have()): ?>
|
||||
<?php while($posts->next()): ?>
|
||||
<tr id="<?php $posts->theId(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $posts->cid(); ?>" name="cid[]"/></td>
|
||||
<td class="kit-hidden-mb"><a href="<?php $options->adminUrl('manage-comments.php?cid=' . ($posts->parentId ? $posts->parentId : $posts->cid)); ?>" class="balloon-button size-<?php echo Typecho_Common::splitByCount($posts->commentsNum, 1, 10, 20, 50, 100); ?>" title="<?php $posts->commentsNum(); ?> <?php _e('评论'); ?>"><?php $posts->commentsNum(); ?></a></td>
|
||||
<td>
|
||||
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"><?php $posts->title(); ?></a>
|
||||
<?php
|
||||
if ($posts->hasSaved || 'post_draft' == $posts->type) {
|
||||
echo '<em class="status">' . _t('草稿') . '</em>';
|
||||
}
|
||||
|
||||
if ('hidden' == $posts->status) {
|
||||
echo '<em class="status">' . _t('隐藏') . '</em>';
|
||||
} else if ('waiting' == $posts->status) {
|
||||
echo '<em class="status">' . _t('待审核') . '</em>';
|
||||
} else if ('private' == $posts->status) {
|
||||
echo '<em class="status">' . _t('私密') . '</em>';
|
||||
} else if ($posts->password) {
|
||||
echo '<em class="status">' . _t('密码保护') . '</em>';
|
||||
}
|
||||
?>
|
||||
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>" title="<?php _e('编辑 %s', htmlspecialchars($posts->title)); ?>"><i class="i-edit"></i></a>
|
||||
<?php if ('post_draft' != $posts->type): ?>
|
||||
<a href="<?php $posts->permalink(); ?>" title="<?php _e('浏览 %s', htmlspecialchars($posts->title)); ?>"><i class="i-exlink"></i></a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><a href="<?php $options->adminUrl('manage-posts.php?uid=' . $posts->author->uid); ?>"><?php $posts->author(); ?></a></td>
|
||||
<td class="kit-hidden-mb"><?php $categories = $posts->categories; $length = count($categories); ?>
|
||||
<?php foreach ($categories as $key => $val): ?>
|
||||
<?php echo '<a href="';
|
||||
$options->adminUrl('manage-posts.php?category=' . $val['mid']
|
||||
. (isset($request->uid) ? '&uid=' . $request->uid : '')
|
||||
. (isset($request->status) ? '&status=' . $request->status : ''));
|
||||
echo '">' . $val['name'] . '</a>' . ($key < $length - 1 ? ', ' : ''); ?>
|
||||
<?php endforeach; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($posts->hasSaved): ?>
|
||||
<span class="description">
|
||||
<?php $modifyDate = new Typecho_Date($posts->modified); ?>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if ($posts->have()): ?>
|
||||
<?php while ($posts->next()): ?>
|
||||
<tr id="<?php $posts->theId(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $posts->cid(); ?>"
|
||||
name="cid[]"/></td>
|
||||
<td class="kit-hidden-mb"><a
|
||||
href="<?php $options->adminUrl('manage-comments.php?cid=' . ($posts->parentId ? $posts->parentId : $posts->cid)); ?>"
|
||||
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($posts->commentsNum, 1, 10, 20, 50, 100); ?>"
|
||||
title="<?php $posts->commentsNum(); ?> <?php _e('评论'); ?>"><?php $posts->commentsNum(); ?></a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"><?php $posts->title(); ?></a>
|
||||
<?php
|
||||
if ($posts->hasSaved || 'post_draft' == $posts->type) {
|
||||
echo '<em class="status">' . _t('草稿') . '</em>';
|
||||
}
|
||||
|
||||
if ('hidden' == $posts->status) {
|
||||
echo '<em class="status">' . _t('隐藏') . '</em>';
|
||||
} elseif ('waiting' == $posts->status) {
|
||||
echo '<em class="status">' . _t('待审核') . '</em>';
|
||||
} elseif ('private' == $posts->status) {
|
||||
echo '<em class="status">' . _t('私密') . '</em>';
|
||||
} elseif ($posts->password) {
|
||||
echo '<em class="status">' . _t('密码保护') . '</em>';
|
||||
}
|
||||
?>
|
||||
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"
|
||||
title="<?php _e('编辑 %s', htmlspecialchars($posts->title)); ?>"><i
|
||||
class="i-edit"></i></a>
|
||||
<?php if ('post_draft' != $posts->type): ?>
|
||||
<a href="<?php $posts->permalink(); ?>"
|
||||
title="<?php _e('浏览 %s', htmlspecialchars($posts->title)); ?>"><i
|
||||
class="i-exlink"></i></a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><a
|
||||
href="<?php $options->adminUrl('manage-posts.php?uid=' . $posts->author->uid); ?>"><?php $posts->author(); ?></a>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><?php $categories = $posts->categories;
|
||||
$length = count($categories); ?>
|
||||
<?php foreach ($categories as $key => $val): ?>
|
||||
<?php echo '<a href="';
|
||||
$options->adminUrl('manage-posts.php?category=' . $val['mid']
|
||||
. (isset($request->uid) ? '&uid=' . $request->uid : '')
|
||||
. (isset($request->status) ? '&status=' . $request->status : ''));
|
||||
echo '">' . $val['name'] . '</a>' . ($key < $length - 1 ? ', ' : ''); ?>
|
||||
<?php endforeach; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($posts->hasSaved): ?>
|
||||
<span class="description">
|
||||
<?php $modifyDate = new \Typecho\Date($posts->modified); ?>
|
||||
<?php _e('保存于 %s', $modifyDate->word()); ?>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<?php $posts->dateWord(); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<?php $posts->dateWord(); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文章'); ?></h6></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文章'); ?></h6>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form><!-- end .operate-form -->
|
||||
|
||||
<div class="typecho-list-operate clearfix">
|
||||
<form method="get">
|
||||
<div class="operate">
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
|
||||
class="typecho-table-select-all"/></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i
|
||||
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>" href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>"
|
||||
href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
|
||||
</li>
|
||||
<?php if ($user->pass('editor', true)): ?>
|
||||
<li><a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a></li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if($posts->have()): ?>
|
||||
<ul class="typecho-pager">
|
||||
<?php $posts->pageNav(); ?>
|
||||
</ul>
|
||||
<?php if ($posts->have()): ?>
|
||||
<ul class="typecho-pager">
|
||||
<?php $posts->pageNav(); ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</div><!-- end .typecho-list-operate -->
|
||||
|
@ -3,54 +3,65 @@ include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
Typecho_Widget::widget('Widget_Metas_Tag_Admin')->to($tags);
|
||||
\Widget\Metas\Tag\Admin::alloc()->to($tags);
|
||||
?>
|
||||
|
||||
<div class="main">
|
||||
<div class="body container">
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main manage-metas">
|
||||
|
||||
<div class="col-mb-12 col-tb-8" role="main">
|
||||
|
||||
<form method="post" name="manage_tags" class="operate-form">
|
||||
|
||||
<div class="col-mb-12 col-tb-8" role="main">
|
||||
|
||||
<form method="post" name="manage_tags" class="operate-form">
|
||||
<div class="typecho-list-operate clearfix">
|
||||
<div class="operate">
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些标签吗?'); ?>" href="<?php $security->index('/action/metas-tag-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
<li><a lang="<?php _e('刷新标签可能需要等待较长时间, 你确认要刷新这些标签吗?'); ?>" href="<?php $security->index('/action/metas-tag-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a></li>
|
||||
<li class="multiline">
|
||||
<button type="button" class="btn btn-s merge" rel="<?php $security->index('/action/metas-tag-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
|
||||
<input type="text" name="merge" class="text-s" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
|
||||
class="typecho-table-select-all"/></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i
|
||||
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些标签吗?'); ?>"
|
||||
href="<?php $security->index('/action/metas-tag-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
|
||||
</li>
|
||||
<li><a lang="<?php _e('刷新标签可能需要等待较长时间, 你确认要刷新这些标签吗?'); ?>"
|
||||
href="<?php $security->index('/action/metas-tag-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a>
|
||||
</li>
|
||||
<li class="multiline">
|
||||
<button type="button" class="btn btn-s merge"
|
||||
rel="<?php $security->index('/action/metas-tag-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
|
||||
<input type="text" name="merge" class="text-s"/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<ul class="typecho-list-notable tag-list clearfix">
|
||||
<?php if($tags->have()): ?>
|
||||
<?php while ($tags->next()): ?>
|
||||
<li class="size-<?php $tags->split(5, 10, 20, 30); ?>" id="<?php $tags->theId(); ?>">
|
||||
<input type="checkbox" value="<?php $tags->mid(); ?>" name="mid[]"/>
|
||||
<span rel="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><?php $tags->name(); ?></span>
|
||||
<a class="tag-edit-link" href="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><i class="i-edit"></i></a>
|
||||
</li>
|
||||
<?php endwhile; ?>
|
||||
<?php if ($tags->have()): ?>
|
||||
<?php while ($tags->next()): ?>
|
||||
<li class="size-<?php $tags->split(5, 10, 20, 30); ?>" id="<?php $tags->theId(); ?>">
|
||||
<input type="checkbox" value="<?php $tags->mid(); ?>" name="mid[]"/>
|
||||
<span
|
||||
rel="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><?php $tags->name(); ?></span>
|
||||
<a class="tag-edit-link"
|
||||
href="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><i
|
||||
class="i-edit"></i></a>
|
||||
</li>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<h6 class="typecho-list-table-title"><?php _e('没有任何标签'); ?></h6>
|
||||
<h6 class="typecho-list-table-title"><?php _e('没有任何标签'); ?></h6>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
<input type="hidden" name="do" value="delete" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div class="col-mb-12 col-tb-4" role="form">
|
||||
<?php Typecho_Widget::widget('Widget_Metas_Tag_Edit')->form()->render(); ?>
|
||||
</div>
|
||||
<input type="hidden" name="do" value="delete"/>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div class="col-mb-12 col-tb-4" role="form">
|
||||
<?php \Widget\Metas\Tag\Edit::alloc()->form()->render(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -61,31 +72,31 @@ include 'common-js.php';
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
$(document).ready(function () {
|
||||
(function () {
|
||||
$(document).ready(function () {
|
||||
|
||||
$('.typecho-list-notable').tableSelectable({
|
||||
checkEl : 'input[type=checkbox]',
|
||||
rowEl : 'li',
|
||||
selectAllEl : '.typecho-table-select-all',
|
||||
actionEl : '.dropdown-menu a'
|
||||
$('.typecho-list-notable').tableSelectable({
|
||||
checkEl: 'input[type=checkbox]',
|
||||
rowEl: 'li',
|
||||
selectAllEl: '.typecho-table-select-all',
|
||||
actionEl: '.dropdown-menu a'
|
||||
});
|
||||
|
||||
$('.btn-drop').dropdownMenu({
|
||||
btnEl: '.dropdown-toggle',
|
||||
menuEl: '.dropdown-menu'
|
||||
});
|
||||
|
||||
$('.dropdown-menu button.merge').click(function () {
|
||||
var btn = $(this);
|
||||
btn.parents('form').attr('action', btn.attr('rel')).submit();
|
||||
});
|
||||
|
||||
<?php if (isset($request->mid)): ?>
|
||||
$('.typecho-mini-panel').effect('highlight', '#AACB36');
|
||||
<?php endif; ?>
|
||||
});
|
||||
|
||||
$('.btn-drop').dropdownMenu({
|
||||
btnEl : '.dropdown-toggle',
|
||||
menuEl : '.dropdown-menu'
|
||||
});
|
||||
|
||||
$('.dropdown-menu button.merge').click(function () {
|
||||
var btn = $(this);
|
||||
btn.parents('form').attr('action', btn.attr('rel')).submit();
|
||||
});
|
||||
|
||||
<?php if (isset($request->mid)): ?>
|
||||
$('.typecho-mini-panel').effect('highlight', '#AACB36');
|
||||
<?php endif; ?>
|
||||
});
|
||||
})();
|
||||
})();
|
||||
</script>
|
||||
<?php include 'footer.php'; ?>
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
$users = \Widget\Users\Admin::alloc();
|
||||
?>
|
||||
<div class="main">
|
||||
<div class="body container">
|
||||
@ -11,97 +13,116 @@ include 'menu.php';
|
||||
<div class="typecho-list-operate clearfix">
|
||||
<form method="get">
|
||||
<div class="operate">
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
|
||||
class="typecho-table-select-all"/></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>" href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i
|
||||
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>"
|
||||
href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search" role="search">
|
||||
<?php if ('' != $request->keywords): ?>
|
||||
<a href="<?php $options->adminUrl('manage-users.php'); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<a href="<?php $options->adminUrl('manage-users.php'); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<?php endif; ?>
|
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords" />
|
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
|
||||
value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords"/>
|
||||
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div><!-- end .typecho-list-operate -->
|
||||
|
||||
<form method="post" name="manage_users" class="operate-form">
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table">
|
||||
<colgroup>
|
||||
<col width="20" class="kit-hidden-mb"/>
|
||||
<col width="6%" class="kit-hidden-mb"/>
|
||||
<col width="30%"/>
|
||||
<col width="" class="kit-hidden-mb"/>
|
||||
<col width="25%" class="kit-hidden-mb"/>
|
||||
<col width="15%"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table">
|
||||
<colgroup>
|
||||
<col width="20" class="kit-hidden-mb"/>
|
||||
<col width="6%" class="kit-hidden-mb"/>
|
||||
<col width="30%"/>
|
||||
<col width="" class="kit-hidden-mb"/>
|
||||
<col width="25%" class="kit-hidden-mb"/>
|
||||
<col width="15%"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="kit-hidden-mb"> </th>
|
||||
<th class="kit-hidden-mb"> </th>
|
||||
<th class="kit-hidden-mb"></th>
|
||||
<th class="kit-hidden-mb"></th>
|
||||
<th><?php _e('用户名'); ?></th>
|
||||
<th class="kit-hidden-mb"><?php _e('昵称'); ?></th>
|
||||
<th class="kit-hidden-mb"><?php _e('电子邮件'); ?></th>
|
||||
<th><?php _e('用户组'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php Typecho_Widget::widget('Widget_Users_Admin')->to($users); ?>
|
||||
<?php while($users->next()): ?>
|
||||
<tr id="user-<?php $users->uid(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $users->uid(); ?>" name="uid[]"/></td>
|
||||
<td class="kit-hidden-mb"><a href="<?php $options->adminUrl('manage-posts.php?uid=' . $users->uid); ?>" class="balloon-button left size-<?php echo Typecho_Common::splitByCount($users->postsNum, 1, 10, 20, 50, 100); ?>"><?php $users->postsNum(); ?></a></td>
|
||||
<td><a href="<?php $options->adminUrl('user.php?uid=' . $users->uid); ?>"><?php $users->name(); ?></a>
|
||||
<a href="<?php $users->permalink(); ?>" title="<?php _e('浏览 %s', $users->screenName); ?>"><i class="i-exlink"></i></a>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><?php $users->screenName(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php if($users->mail): ?><a href="mailto:<?php $users->mail(); ?>"><?php $users->mail(); ?></a><?php else: _e('暂无'); endif; ?></td>
|
||||
<td><?php switch ($users->group) {
|
||||
case 'administrator':
|
||||
_e('管理员');
|
||||
break;
|
||||
case 'editor':
|
||||
_e('编辑');
|
||||
break;
|
||||
case 'contributor':
|
||||
_e('贡献者');
|
||||
break;
|
||||
case 'subscriber':
|
||||
_e('关注者');
|
||||
break;
|
||||
case 'visitor':
|
||||
_e('访问者');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} ?></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($users->next()): ?>
|
||||
<tr id="user-<?php $users->uid(); ?>">
|
||||
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $users->uid(); ?>"
|
||||
name="uid[]"/></td>
|
||||
<td class="kit-hidden-mb"><a
|
||||
href="<?php $options->adminUrl('manage-posts.php?uid=' . $users->uid); ?>"
|
||||
class="balloon-button left size-<?php echo \Typecho\Common::splitByCount($users->postsNum, 1, 10, 20, 50, 100); ?>"><?php $users->postsNum(); ?></a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php $options->adminUrl('user.php?uid=' . $users->uid); ?>"><?php $users->name(); ?></a>
|
||||
<a href="<?php $users->permalink(); ?>"
|
||||
title="<?php _e('浏览 %s', $users->screenName); ?>"><i
|
||||
class="i-exlink"></i></a>
|
||||
</td>
|
||||
<td class="kit-hidden-mb"><?php $users->screenName(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php if ($users->mail): ?><a
|
||||
href="mailto:<?php $users->mail(); ?>"><?php $users->mail(); ?></a><?php else: _e('暂无'); endif; ?>
|
||||
</td>
|
||||
<td><?php switch ($users->group) {
|
||||
case 'administrator':
|
||||
_e('管理员');
|
||||
break;
|
||||
case 'editor':
|
||||
_e('编辑');
|
||||
break;
|
||||
case 'contributor':
|
||||
_e('贡献者');
|
||||
break;
|
||||
case 'subscriber':
|
||||
_e('关注者');
|
||||
break;
|
||||
case 'visitor':
|
||||
_e('访问者');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} ?></td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table><!-- end .typecho-list-table -->
|
||||
</div><!-- end .typecho-table-wrap -->
|
||||
</tbody>
|
||||
</table><!-- end .typecho-list-table -->
|
||||
</div><!-- end .typecho-table-wrap -->
|
||||
</form><!-- end .operate-form -->
|
||||
|
||||
<div class="typecho-list-operate clearfix">
|
||||
<form method="get">
|
||||
<div class="operate">
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
|
||||
class="typecho-table-select-all"/></label>
|
||||
<div class="btn-group btn-drop">
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>" href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<button class="btn dropdown-toggle btn-s" type="button"><i
|
||||
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>"
|
||||
href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php if($users->have()): ?>
|
||||
<ul class="typecho-pager">
|
||||
<?php $users->pageNav(); ?>
|
||||
</ul>
|
||||
<?php if ($users->have()): ?>
|
||||
<ul class="typecho-pager">
|
||||
<?php $users->pageNav(); ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</div><!-- end .typecho-list-operate -->
|
||||
|
282
admin/media.php
282
admin/media.php
@ -9,7 +9,7 @@ if (preg_match("/^([0-9]+)([a-z]{1,2})$/i", $phpMaxFilesize, $matches)) {
|
||||
$phpMaxFilesize = strtolower($matches[1] . $matches[2] . (1 == strlen($matches[2]) ? 'b' : ''));
|
||||
}
|
||||
|
||||
Typecho_Widget::widget('Widget_Contents_Attachment_Edit')->to($attachment);
|
||||
$attachment = \Widget\Contents\Attachment\Edit::alloc();
|
||||
?>
|
||||
|
||||
<div class="main">
|
||||
@ -18,22 +18,25 @@ Typecho_Widget::widget('Widget_Contents_Attachment_Edit')->to($attachment);
|
||||
<div class="row typecho-page-main">
|
||||
<div class="col-mb-12 col-tb-8" role="main">
|
||||
<?php if ($attachment->attachment->isImage): ?>
|
||||
<p><img src="<?php $attachment->attachment->url(); ?>" alt="<?php $attachment->attachment->name(); ?>" class="typecho-attachment-photo" /></p>
|
||||
<p><img src="<?php $attachment->attachment->url(); ?>"
|
||||
alt="<?php $attachment->attachment->name(); ?>" class="typecho-attachment-photo"/></p>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<p>
|
||||
<?php $mime = Typecho_Common::mimeIconType($attachment->attachment->mime); ?>
|
||||
<?php $mime = \Typecho\Common::mimeIconType($attachment->attachment->mime); ?>
|
||||
<i class="mime-<?php echo $mime; ?>"></i>
|
||||
<a href=""><strong><?php $attachment->attachment->name(); ?></strong></a>
|
||||
<span><?php echo number_format(ceil($attachment->attachment->size / 1024)); ?> Kb</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input id="attachment-url" type="text" class="mono w-100" value="<?php $attachment->attachment->url(); ?>" readonly />
|
||||
<input id="attachment-url" type="text" class="mono w-100"
|
||||
value="<?php $attachment->attachment->url(); ?>" readonly/>
|
||||
</p>
|
||||
|
||||
<div id="upload-panel" class="p">
|
||||
<div class="upload-area" draggable="true"><?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?></div>
|
||||
<div class="upload-area"
|
||||
draggable="true"><?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?></div>
|
||||
<ul id="file-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -51,143 +54,146 @@ include 'common-js.php';
|
||||
<script src="<?php $options->adminStaticUrl('js', 'moxie.js'); ?>"></script>
|
||||
<script src="<?php $options->adminStaticUrl('js', 'plupload.js'); ?>"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#attachment-url').click(function () {
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
$('.operate-delete').click(function () {
|
||||
var t = $(this), href = t.attr('href');
|
||||
|
||||
if (confirm(t.attr('lang'))) {
|
||||
window.location.href = href;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.upload-area').bind({
|
||||
dragenter : function () {
|
||||
$(this).parent().addClass('drag');
|
||||
},
|
||||
|
||||
dragover : function (e) {
|
||||
$(this).parent().addClass('drag');
|
||||
},
|
||||
|
||||
drop : function () {
|
||||
$(this).parent().removeClass('drag');
|
||||
},
|
||||
|
||||
dragend : function () {
|
||||
$(this).parent().removeClass('drag');
|
||||
},
|
||||
|
||||
dragleave : function () {
|
||||
$(this).parent().removeClass('drag');
|
||||
}
|
||||
});
|
||||
|
||||
function fileUploadStart (file) {
|
||||
$('<ul id="file-list"></ul>').appendTo('#upload-panel');
|
||||
$('<li id="' + file.id + '" class="loading">'
|
||||
+ file.name + '</li>').prependTo('#file-list');
|
||||
}
|
||||
|
||||
function fileUploadError (error) {
|
||||
var file = error.file, code = error.code, word;
|
||||
|
||||
switch (code) {
|
||||
case plupload.FILE_SIZE_ERROR:
|
||||
word = '<?php _e('文件大小超过限制'); ?>';
|
||||
break;
|
||||
case plupload.FILE_EXTENSION_ERROR:
|
||||
word = '<?php _e('文件扩展名不被支持'); ?>';
|
||||
break;
|
||||
case plupload.FILE_DUPLICATE_ERROR:
|
||||
word = '<?php _e('文件已经上传过'); ?>';
|
||||
break;
|
||||
case plupload.HTTP_ERROR:
|
||||
default:
|
||||
word = '<?php _e('上传出现错误'); ?>';
|
||||
break;
|
||||
}
|
||||
|
||||
var fileError = '<?php _e('%s 上传失败'); ?>'.replace('%s', file.name),
|
||||
li, exist = $('#' + file.id);
|
||||
|
||||
if (exist.length > 0) {
|
||||
li = exist.removeClass('loading').html(fileError);
|
||||
} else {
|
||||
$('<ul id="file-list"></ul>').appendTo('#upload-panel');
|
||||
li = $('<li>' + fileError + '<br />' + word + '</li>').prependTo('#file-list');
|
||||
}
|
||||
|
||||
li.effect('highlight', {color : '#FBC2C4'}, 2000, function () {
|
||||
$(this).remove();
|
||||
$(document).ready(function () {
|
||||
$('#attachment-url').click(function () {
|
||||
$(this).select();
|
||||
});
|
||||
}
|
||||
|
||||
function fileUploadComplete (id, url, data) {
|
||||
var img = $('.typecho-attachment-photo');
|
||||
$('.operate-delete').click(function () {
|
||||
var t = $(this), href = t.attr('href');
|
||||
|
||||
if (img.length > 0) {
|
||||
img.get(0).src = '<?php $attachment->attachment->url(); ?>?' + Math.random();
|
||||
}
|
||||
|
||||
$('#' + id).html('<?php _e('文件 %s 已经替换'); ?>'.replace('%s', data.title))
|
||||
.effect('highlight', 1000, function () {
|
||||
$(this).remove();
|
||||
$('#file-list').remove();
|
||||
});
|
||||
}
|
||||
|
||||
var uploader = new plupload.Uploader({
|
||||
browse_button : $('.upload-file').get(0),
|
||||
url : '<?php $security->index('/action/upload?do=modify&cid=' . $attachment->cid); ?>',
|
||||
runtimes : 'html5,flash,html4',
|
||||
flash_swf_url : '<?php $options->adminStaticUrl('js', 'Moxie.swf'); ?>',
|
||||
drop_element : $('.upload-area').get(0),
|
||||
filters : {
|
||||
max_file_size : '<?php echo $phpMaxFilesize ?>',
|
||||
mime_types : [{'title' : '<?php _e('允许上传的文件'); ?>', 'extensions' : '<?php $attachment->attachment->type(); ?>'}],
|
||||
prevent_duplicates : true
|
||||
},
|
||||
multi_selection : false,
|
||||
|
||||
init : {
|
||||
FilesAdded : function (up, files) {
|
||||
plupload.each(files, function(file) {
|
||||
fileUploadStart(file);
|
||||
});
|
||||
|
||||
uploader.start();
|
||||
},
|
||||
|
||||
FileUploaded : function (up, file, result) {
|
||||
if (200 == result.status) {
|
||||
var data = $.parseJSON(result.response);
|
||||
|
||||
if (data) {
|
||||
fileUploadComplete(file.id, data[0], data[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fileUploadError({
|
||||
code : plupload.HTTP_ERROR,
|
||||
file : file
|
||||
});
|
||||
},
|
||||
|
||||
Error : function (up, error) {
|
||||
fileUploadError(error);
|
||||
if (confirm(t.attr('lang'))) {
|
||||
window.location.href = href;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
uploader.init();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.upload-area').bind({
|
||||
dragenter: function () {
|
||||
$(this).parent().addClass('drag');
|
||||
},
|
||||
|
||||
dragover: function (e) {
|
||||
$(this).parent().addClass('drag');
|
||||
},
|
||||
|
||||
drop: function () {
|
||||
$(this).parent().removeClass('drag');
|
||||
},
|
||||
|
||||
dragend: function () {
|
||||
$(this).parent().removeClass('drag');
|
||||
},
|
||||
|
||||
dragleave: function () {
|
||||
$(this).parent().removeClass('drag');
|
||||
}
|
||||
});
|
||||
|
||||
function fileUploadStart(file) {
|
||||
$('<ul id="file-list"></ul>').appendTo('#upload-panel');
|
||||
$('<li id="' + file.id + '" class="loading">'
|
||||
+ file.name + '</li>').prependTo('#file-list');
|
||||
}
|
||||
|
||||
function fileUploadError(error) {
|
||||
var file = error.file, code = error.code, word;
|
||||
|
||||
switch (code) {
|
||||
case plupload.FILE_SIZE_ERROR:
|
||||
word = '<?php _e('文件大小超过限制'); ?>';
|
||||
break;
|
||||
case plupload.FILE_EXTENSION_ERROR:
|
||||
word = '<?php _e('文件扩展名不被支持'); ?>';
|
||||
break;
|
||||
case plupload.FILE_DUPLICATE_ERROR:
|
||||
word = '<?php _e('文件已经上传过'); ?>';
|
||||
break;
|
||||
case plupload.HTTP_ERROR:
|
||||
default:
|
||||
word = '<?php _e('上传出现错误'); ?>';
|
||||
break;
|
||||
}
|
||||
|
||||
var fileError = '<?php _e('%s 上传失败'); ?>'.replace('%s', file.name),
|
||||
li, exist = $('#' + file.id);
|
||||
|
||||
if (exist.length > 0) {
|
||||
li = exist.removeClass('loading').html(fileError);
|
||||
} else {
|
||||
$('<ul id="file-list"></ul>').appendTo('#upload-panel');
|
||||
li = $('<li>' + fileError + '<br />' + word + '</li>').prependTo('#file-list');
|
||||
}
|
||||
|
||||
li.effect('highlight', {color: '#FBC2C4'}, 2000, function () {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
|
||||
function fileUploadComplete(id, url, data) {
|
||||
var img = $('.typecho-attachment-photo');
|
||||
|
||||
if (img.length > 0) {
|
||||
img.get(0).src = '<?php $attachment->attachment->url(); ?>?' + Math.random();
|
||||
}
|
||||
|
||||
$('#' + id).html('<?php _e('文件 %s 已经替换'); ?>'.replace('%s', data.title))
|
||||
.effect('highlight', 1000, function () {
|
||||
$(this).remove();
|
||||
$('#file-list').remove();
|
||||
});
|
||||
}
|
||||
|
||||
var uploader = new plupload.Uploader({
|
||||
browse_button: $('.upload-file').get(0),
|
||||
url: '<?php $security->index('/action/upload?do=modify&cid=' . $attachment->cid); ?>',
|
||||
runtimes: 'html5,flash,html4',
|
||||
flash_swf_url: '<?php $options->adminStaticUrl('js', 'Moxie.swf'); ?>',
|
||||
drop_element: $('.upload-area').get(0),
|
||||
filters: {
|
||||
max_file_size: '<?php echo $phpMaxFilesize ?>',
|
||||
mime_types: [{
|
||||
'title': '<?php _e('允许上传的文件'); ?>',
|
||||
'extensions': '<?php $attachment->attachment->type(); ?>'
|
||||
}],
|
||||
prevent_duplicates: true
|
||||
},
|
||||
multi_selection: false,
|
||||
|
||||
init: {
|
||||
FilesAdded: function (up, files) {
|
||||
plupload.each(files, function (file) {
|
||||
fileUploadStart(file);
|
||||
});
|
||||
|
||||
uploader.start();
|
||||
},
|
||||
|
||||
FileUploaded: function (up, file, result) {
|
||||
if (200 == result.status) {
|
||||
var data = $.parseJSON(result.response);
|
||||
|
||||
if (data) {
|
||||
fileUploadComplete(file.id, data[0], data[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fileUploadError({
|
||||
code: plupload.HTTP_ERROR,
|
||||
file: file
|
||||
});
|
||||
},
|
||||
|
||||
Error: function (up, error) {
|
||||
fileUploadError(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
uploader.init();
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
include 'footer.php';
|
||||
|
@ -1,16 +1,18 @@
|
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
|
||||
<?php if (!defined('__TYPECHO_ADMIN__')) exit; ?>
|
||||
<div class="typecho-head-nav clearfix" role="navigation">
|
||||
<button class="menu-bar"><?php _e('菜单'); ?></button>
|
||||
<nav id="typecho-nav-list">
|
||||
<?php $menu->output(); ?>
|
||||
</nav>
|
||||
<div class="operate">
|
||||
<?php Typecho_Plugin::factory('admin/menu.php')->navBar(); ?><a title="<?php
|
||||
if ($user->logged > 0) {
|
||||
$logged = new Typecho_Date($user->logged);
|
||||
_e('最后登录: %s', $logged->word());
|
||||
}
|
||||
?>" href="<?php $options->adminUrl('profile.php'); ?>" class="author"><?php $user->screenName(); ?></a><a class="exit" href="<?php $options->logoutUrl(); ?>"><?php _e('登出'); ?></a><a href="<?php $options->siteUrl(); ?>"><?php _e('网站'); ?></a>
|
||||
<?php \Typecho\Plugin::factory('admin/menu.php')->navBar(); ?><a title="<?php
|
||||
if ($user->logged > 0) {
|
||||
$logged = new \Typecho\Date($user->logged);
|
||||
_e('最后登录: %s', $logged->word());
|
||||
}
|
||||
?>" href="<?php $options->adminUrl('profile.php'); ?>" class="author"><?php $user->screenName(); ?></a><a
|
||||
class="exit" href="<?php $options->logoutUrl(); ?>"><?php _e('登出'); ?></a><a
|
||||
href="<?php $options->siteUrl(); ?>"><?php _e('网站'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -9,7 +9,7 @@ include 'menu.php';
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main" role="form">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
<?php Typecho_Widget::widget('Widget_Options_Discussion')->form()->render(); ?>
|
||||
<?php \Widget\Options\Discussion::alloc()->form()->render(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@ include 'menu.php';
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main" role="form">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
<?php Typecho_Widget::widget('Widget_Options_General')->form()->render(); ?>
|
||||
<?php \Widget\Options\General::alloc()->form()->render(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@ include 'menu.php';
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main" role="form">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
<?php Typecho_Widget::widget('Widget_Options_Permalink')->form()->render(); ?>
|
||||
<?php \Widget\Options\Permalink::alloc()->form()->render(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@ include 'menu.php';
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main" role="form">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
<?php Typecho_Widget::widget('Widget_Plugins_Config')->config()->render(); ?>
|
||||
<?php \Widget\Plugins\Config::alloc()->config()->render(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@ include 'menu.php';
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main" role="form">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
<?php Typecho_Widget::widget('Widget_Options_Reading')->form()->render(); ?>
|
||||
<?php \Widget\Options\Reading::alloc()->form()->render(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -14,11 +14,12 @@ include 'menu.php';
|
||||
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?>
|
||||
<li><a href="<?php $options->adminUrl('theme-editor.php'); ?>"><?php _e('编辑当前外观'); ?></a></li>
|
||||
<?php endif; ?>
|
||||
<li class="current"><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
|
||||
<li class="current"><a
|
||||
href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2" role="form">
|
||||
<?php Typecho_Widget::widget('Widget_Themes_Config')->config()->render(); ?>
|
||||
<?php \Widget\Themes\Config::alloc()->config()->render(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -8,19 +8,19 @@ include 'menu.php';
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main" role="main">
|
||||
<div class="col-mb-12 typecho-list">
|
||||
<?php Typecho_Widget::widget('Widget_Plugins_List@activated', 'activated=1')->to($activatedPlugins); ?>
|
||||
<?php \Widget\Plugins\Rows::allocWithAlias('activated', 'activated=1')->to($activatedPlugins); ?>
|
||||
<?php if ($activatedPlugins->have() || !empty($activatedPlugins->activatedPlugins)): ?>
|
||||
<h4 class="typecho-list-table-title"><?php _e('启用的插件'); ?></h4>
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table">
|
||||
<colgroup>
|
||||
<col width="25%"/>
|
||||
<col width="45%"/>
|
||||
<col width="8%" class="kit-hidden-mb"/>
|
||||
<col width="10%" class="kit-hidden-mb"/>
|
||||
<col width=""/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<h4 class="typecho-list-table-title"><?php _e('启用的插件'); ?></h4>
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table">
|
||||
<colgroup>
|
||||
<col width="25%"/>
|
||||
<col width="45%"/>
|
||||
<col width="8%" class="kit-hidden-mb"/>
|
||||
<col width="10%" class="kit-hidden-mb"/>
|
||||
<col width=""/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('名称'); ?></th>
|
||||
<th><?php _e('描述'); ?></th>
|
||||
@ -28,61 +28,66 @@ include 'menu.php';
|
||||
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
|
||||
<th><?php _e('操作'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($activatedPlugins->next()): ?>
|
||||
<tr id="plugin-<?php $activatedPlugins->name(); ?>">
|
||||
<td><?php $activatedPlugins->title(); ?>
|
||||
<?php if (!$activatedPlugins->dependence): ?>
|
||||
<i class="i-delete" title="<?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?>"></i>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php $activatedPlugins->description(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php $activatedPlugins->version(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php echo empty($activatedPlugins->homepage) ? $activatedPlugins->author : '<a href="' . $activatedPlugins->homepage
|
||||
. '">' . $activatedPlugins->author . '</a>'; ?></td>
|
||||
<td>
|
||||
<?php if ($activatedPlugins->activate || $activatedPlugins->deactivate || $activatedPlugins->config || $activatedPlugins->personalConfig): ?>
|
||||
<?php if ($activatedPlugins->config): ?>
|
||||
<a href="<?php $options->adminUrl('options-plugin.php?config=' . $activatedPlugins->name); ?>"><?php _e('设置'); ?></a>
|
||||
•
|
||||
<tr id="plugin-<?php $activatedPlugins->name(); ?>">
|
||||
<td><?php $activatedPlugins->title(); ?>
|
||||
<?php if (!$activatedPlugins->dependence): ?>
|
||||
<i class="i-delete"
|
||||
title="<?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?>"></i>
|
||||
<?php endif; ?>
|
||||
<a lang="<?php _e('你确认要禁用插件 %s 吗?', $activatedPlugins->name); ?>" href="<?php $security->index('/action/plugins-edit?deactivate=' . $activatedPlugins->name); ?>"><?php _e('禁用'); ?></a>
|
||||
<?php else: ?>
|
||||
<span class="important"><?php _e('即插即用'); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
</td>
|
||||
<td><?php $activatedPlugins->description(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php $activatedPlugins->version(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php echo empty($activatedPlugins->homepage) ? $activatedPlugins->author : '<a href="' . $activatedPlugins->homepage
|
||||
. '">' . $activatedPlugins->author . '</a>'; ?></td>
|
||||
<td>
|
||||
<?php if ($activatedPlugins->activate || $activatedPlugins->deactivate || $activatedPlugins->config || $activatedPlugins->personalConfig): ?>
|
||||
<?php if ($activatedPlugins->config): ?>
|
||||
<a href="<?php $options->adminUrl('options-plugin.php?config=' . $activatedPlugins->name); ?>"><?php _e('设置'); ?></a>
|
||||
•
|
||||
<?php endif; ?>
|
||||
<a lang="<?php _e('你确认要禁用插件 %s 吗?', $activatedPlugins->name); ?>"
|
||||
href="<?php $security->index('/action/plugins-edit?deactivate=' . $activatedPlugins->name); ?>"><?php _e('禁用'); ?></a>
|
||||
<?php else: ?>
|
||||
<span class="important"><?php _e('即插即用'); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
|
||||
|
||||
<?php if (!empty($activatedPlugins->activatedPlugins)): ?>
|
||||
<?php foreach ($activatedPlugins->activatedPlugins as $key => $val): ?>
|
||||
<tr>
|
||||
<td><?php echo $key; ?></td>
|
||||
<td colspan="3"><span class="warning"><?php _e('此插件文件已经损坏或者被不安全移除, 强烈建议你禁用它'); ?></span></td>
|
||||
<td><a lang="<?php _e('你确认要禁用插件 %s 吗?', $key); ?>" href="<?php $security->index('/action/plugins-edit?deactivate=' . $key); ?>"><?php _e('禁用'); ?></a></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($activatedPlugins->activatedPlugins as $key => $val): ?>
|
||||
<tr>
|
||||
<td><?php echo $key; ?></td>
|
||||
<td colspan="3"><span
|
||||
class="warning"><?php _e('此插件文件已经损坏或者被不安全移除, 强烈建议你禁用它'); ?></span></td>
|
||||
<td><a lang="<?php _e('你确认要禁用插件 %s 吗?', $key); ?>"
|
||||
href="<?php $security->index('/action/plugins-edit?deactivate=' . $key); ?>"><?php _e('禁用'); ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php Typecho_Widget::widget('Widget_Plugins_List@unactivated', 'activated=0')->to($deactivatedPlugins); ?>
|
||||
|
||||
<?php \Widget\Plugins\Rows::allocWithAlias('unactivated', 'activated=0')->to($deactivatedPlugins); ?>
|
||||
<?php if ($deactivatedPlugins->have() || !$activatedPlugins->have()): ?>
|
||||
<h4 class="typecho-list-table-title"><?php _e('禁用的插件'); ?></h4>
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table deactivate">
|
||||
<colgroup>
|
||||
<col width="25%"/>
|
||||
<col width="45%"/>
|
||||
<col width="8%" class="kit-hidden-mb"/>
|
||||
<col width="10%" class="kit-hidden-mb"/>
|
||||
<col width=""/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<h4 class="typecho-list-table-title"><?php _e('禁用的插件'); ?></h4>
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table deactivate">
|
||||
<colgroup>
|
||||
<col width="25%"/>
|
||||
<col width="45%"/>
|
||||
<col width="8%" class="kit-hidden-mb"/>
|
||||
<col width="10%" class="kit-hidden-mb"/>
|
||||
<col width=""/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('名称'); ?></th>
|
||||
<th><?php _e('描述'); ?></th>
|
||||
@ -90,31 +95,32 @@ include 'menu.php';
|
||||
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
|
||||
<th class="typecho-radius-topright"><?php _e('操作'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if ($deactivatedPlugins->have()): ?>
|
||||
<?php while ($deactivatedPlugins->next()): ?>
|
||||
<tr id="plugin-<?php $deactivatedPlugins->name(); ?>">
|
||||
<td><?php $deactivatedPlugins->title(); ?></td>
|
||||
<td><?php $deactivatedPlugins->description(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php $deactivatedPlugins->version(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php echo empty($deactivatedPlugins->homepage) ? $deactivatedPlugins->author : '<a href="' . $deactivatedPlugins->homepage
|
||||
. '">' . $deactivatedPlugins->author . '</a>'; ?></td>
|
||||
<td>
|
||||
<a href="<?php $security->index('/action/plugins-edit?activate=' . $deactivatedPlugins->name); ?>"><?php _e('启用'); ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
<?php while ($deactivatedPlugins->next()): ?>
|
||||
<tr id="plugin-<?php $deactivatedPlugins->name(); ?>">
|
||||
<td><?php $deactivatedPlugins->title(); ?></td>
|
||||
<td><?php $deactivatedPlugins->description(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php $deactivatedPlugins->version(); ?></td>
|
||||
<td class="kit-hidden-mb"><?php echo empty($deactivatedPlugins->homepage) ? $deactivatedPlugins->author : '<a href="' . $deactivatedPlugins->homepage
|
||||
. '">' . $deactivatedPlugins->author . '</a>'; ?></td>
|
||||
<td>
|
||||
<a href="<?php $security->index('/action/plugins-edit?activate=' . $deactivatedPlugins->name); ?>"><?php _e('启用'); ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="5"><h6 class="typecho-list-table-title"><?php _e('没有安装插件'); ?></h6></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="5"><h6 class="typecho-list-table-title"><?php _e('没有安装插件'); ?></h6>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,7 +3,7 @@
|
||||
include 'common.php';
|
||||
|
||||
/** 获取内容 Widget */
|
||||
Typecho_Widget::widget('Widget_Archive', 'type=single&checkPermalink=0&preview=1')->to($content);
|
||||
\Widget\Archive::alloc('type=single&checkPermalink=0&preview=1')->to($content);
|
||||
|
||||
/** 检测是否存在 */
|
||||
if (!$content->have()) {
|
||||
@ -24,4 +24,4 @@ $content->render();
|
||||
window.parent.postMessage('cancelPreview', '<?php $options->rootUrl(); ?>');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
@ -3,7 +3,7 @@ include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat');
|
||||
$stat = \Widget\Stat::alloc();
|
||||
?>
|
||||
|
||||
<div class="main">
|
||||
@ -11,41 +11,43 @@ $stat = Typecho_Widget::widget('Widget_Stat');
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main">
|
||||
<div class="col-mb-12 col-tb-3">
|
||||
<p><a href="http://gravatar.com/emails/" title="<?php _e('在 Gravatar 上修改头像'); ?>"><?php echo '<img class="profile-avatar" src="' . Typecho_Common::gravatarUrl($user->mail, 220, 'X', 'mm', $request->isSecure()) . '" alt="' . $user->screenName . '" />'; ?></a></p>
|
||||
<p><a href="http://gravatar.com/emails/"
|
||||
title="<?php _e('在 Gravatar 上修改头像'); ?>"><?php echo '<img class="profile-avatar" src="' . \Typecho\Common::gravatarUrl($user->mail, 220, 'X', 'mm', $request->isSecure()) . '" alt="' . $user->screenName . '" />'; ?></a>
|
||||
</p>
|
||||
<h2><?php $user->screenName(); ?></h2>
|
||||
<p><?php $user->name(); ?></p>
|
||||
<p><?php _e('目前有 <em>%s</em> 篇日志, 并有 <em>%s</em> 条关于你的评论在 <em>%s</em> 个分类中.',
|
||||
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?></p>
|
||||
<p><?php _e('目前有 <em>%s</em> 篇日志, 并有 <em>%s</em> 条关于你的评论在 <em>%s</em> 个分类中.',
|
||||
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?></p>
|
||||
<p><?php
|
||||
if ($user->logged > 0) {
|
||||
$logged = new Typecho_Date($user->logged);
|
||||
_e('最后登录: %s', $logged->word());
|
||||
}
|
||||
?></p>
|
||||
if ($user->logged > 0) {
|
||||
$logged = new \Typecho\Date($user->logged);
|
||||
_e('最后登录: %s', $logged->word());
|
||||
}
|
||||
?></p>
|
||||
</div>
|
||||
|
||||
<div class="col-mb-12 col-tb-6 col-tb-offset-1 typecho-content-panel" role="form">
|
||||
<section>
|
||||
<h3><?php _e('个人资料'); ?></h3>
|
||||
<?php Typecho_Widget::widget('Widget_Users_Profile')->profileForm()->render(); ?>
|
||||
<?php \Widget\Users\Profile::alloc()->profileForm()->render(); ?>
|
||||
</section>
|
||||
|
||||
<?php if($user->pass('contributor', true)): ?>
|
||||
<br>
|
||||
<section id="writing-option">
|
||||
<h3><?php _e('撰写设置'); ?></h3>
|
||||
<?php Typecho_Widget::widget('Widget_Users_Profile')->optionsForm()->render(); ?>
|
||||
</section>
|
||||
<?php if ($user->pass('contributor', true)): ?>
|
||||
<br>
|
||||
<section id="writing-option">
|
||||
<h3><?php _e('撰写设置'); ?></h3>
|
||||
<?php \Widget\Users\Profile::alloc()->optionsForm()->render(); ?>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<br>
|
||||
|
||||
<section id="change-password">
|
||||
<h3><?php _e('密码修改'); ?></h3>
|
||||
<?php Typecho_Widget::widget('Widget_Users_Profile')->passwordForm()->render(); ?>
|
||||
<?php \Widget\Users\Profile::alloc()->passwordForm()->render(); ?>
|
||||
</section>
|
||||
|
||||
<?php Typecho_Widget::widget('Widget_Users_Profile')->personalFormList(); ?>
|
||||
<?php \Widget\Users\Profile::alloc()->personalFormList(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -55,6 +57,6 @@ $stat = Typecho_Widget::widget('Widget_Stat');
|
||||
include 'copyright.php';
|
||||
include 'common-js.php';
|
||||
include 'form-js.php';
|
||||
Typecho_Plugin::factory('admin/profile.php')->bottom();
|
||||
\Typecho\Plugin::factory('admin/profile.php')->bottom();
|
||||
include 'footer.php';
|
||||
?>
|
||||
|
@ -4,10 +4,10 @@ include 'common.php';
|
||||
if ($user->hasLogin() || !$options->allowRegister) {
|
||||
$response->redirect($options->siteUrl);
|
||||
}
|
||||
$rememberName = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_name'));
|
||||
$rememberMail = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_mail'));
|
||||
Typecho_Cookie::delete('__typecho_remember_name');
|
||||
Typecho_Cookie::delete('__typecho_remember_mail');
|
||||
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name'));
|
||||
$rememberMail = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_mail'));
|
||||
\Typecho\Cookie::delete('__typecho_remember_name');
|
||||
\Typecho\Cookie::delete('__typecho_remember_mail');
|
||||
|
||||
$bodyClass = 'body-100';
|
||||
|
||||
|
@ -11,6 +11,10 @@ textarea {
|
||||
border-radius: 2px;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
&:disabled, &:read-only {
|
||||
background: #F3F3F3;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
|
@ -78,12 +78,6 @@ a.button:hover, a.balloon-button:hover {
|
||||
@import "header";
|
||||
@import "footer";
|
||||
|
||||
/* 低版本浏览器升级提示 */
|
||||
.browsehappy {
|
||||
border: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/** 顶部消息样式 by 70 */
|
||||
.popup {
|
||||
display: none;
|
||||
|
@ -3,7 +3,7 @@ include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
Typecho_Widget::widget('Widget_Themes_Files')->to($files);
|
||||
\Widget\Themes\Files::alloc()->to($files);
|
||||
?>
|
||||
|
||||
<div class="main">
|
||||
@ -14,28 +14,30 @@ Typecho_Widget::widget('Widget_Themes_Files')->to($files);
|
||||
<ul class="typecho-option-tabs fix-tabs clearfix">
|
||||
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
|
||||
<li class="current"><a href="<?php $options->adminUrl('theme-editor.php'); ?>">
|
||||
<?php if ($options->theme == $files->theme): ?>
|
||||
<?php _e('编辑当前外观'); ?>
|
||||
<?php else: ?>
|
||||
<?php _e('编辑%s外观', ' <cite>' . $files->theme . '</cite> '); ?>
|
||||
<?php endif; ?>
|
||||
</a></li>
|
||||
<?php if (Widget_Themes_Config::isExists()): ?>
|
||||
<li><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
|
||||
<?php if ($options->theme == $files->theme): ?>
|
||||
<?php _e('编辑当前外观'); ?>
|
||||
<?php else: ?>
|
||||
<?php _e('编辑%s外观', ' <cite>' . $files->theme . '</cite> '); ?>
|
||||
<?php endif; ?>
|
||||
</a></li>
|
||||
<?php if (\Widget\Themes\Config::isExists()): ?>
|
||||
<li><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="typecho-edit-theme">
|
||||
<div class="col-mb-12 col-tb-8 col-9 content">
|
||||
<form method="post" name="theme" id="theme" action="<?php $security->index('/action/themes-edit'); ?>">
|
||||
<form method="post" name="theme" id="theme"
|
||||
action="<?php $security->index('/action/themes-edit'); ?>">
|
||||
<label for="content" class="sr-only"><?php _e('编辑源码'); ?></label>
|
||||
<textarea name="content" id="content" class="w-100 mono" <?php if(!$files->currentIsWriteable()): ?>readonly<?php endif; ?>><?php echo $files->currentContent(); ?></textarea>
|
||||
<textarea name="content" id="content" class="w-100 mono"
|
||||
<?php if (!$files->currentIsWriteable()): ?>readonly<?php endif; ?>><?php echo $files->currentContent(); ?></textarea>
|
||||
<p class="typecho-option typecho-option-submit">
|
||||
<?php if($files->currentIsWriteable()): ?>
|
||||
<input type="hidden" name="theme" value="<?php echo $files->currentTheme(); ?>" />
|
||||
<input type="hidden" name="edit" value="<?php echo $files->currentFile(); ?>" />
|
||||
<button type="submit" class="btn primary"><?php _e('保存文件'); ?></button>
|
||||
<?php if ($files->currentIsWriteable()): ?>
|
||||
<input type="hidden" name="theme" value="<?php echo $files->currentTheme(); ?>"/>
|
||||
<input type="hidden" name="edit" value="<?php echo $files->currentFile(); ?>"/>
|
||||
<button type="submit" class="btn primary"><?php _e('保存文件'); ?></button>
|
||||
<?php else: ?>
|
||||
<em><?php _e('此文件无法写入'); ?></em>
|
||||
<?php endif; ?>
|
||||
@ -44,9 +46,10 @@ Typecho_Widget::widget('Widget_Themes_Files')->to($files);
|
||||
</div>
|
||||
<ul class="col-mb-12 col-tb-4 col-3">
|
||||
<li><strong>模板文件</strong></li>
|
||||
<?php while($files->next()): ?>
|
||||
<li<?php if($files->current): ?> class="current"<?php endif; ?>>
|
||||
<a href="<?php $options->adminUrl('theme-editor.php?theme=' . $files->currentTheme() . '&file=' . $files->file); ?>"><?php $files->file(); ?></a></li>
|
||||
<?php while ($files->next()): ?>
|
||||
<li<?php if ($files->current): ?> class="current"<?php endif; ?>>
|
||||
<a href="<?php $options->adminUrl('theme-editor.php?theme=' . $files->currentTheme() . '&file=' . $files->file); ?>"><?php $files->file(); ?></a>
|
||||
</li>
|
||||
<?php endwhile; ?>
|
||||
</ul>
|
||||
</div>
|
||||
@ -57,6 +60,6 @@ Typecho_Widget::widget('Widget_Themes_Files')->to($files);
|
||||
<?php
|
||||
include 'copyright.php';
|
||||
include 'common-js.php';
|
||||
Typecho_Plugin::factory('admin/theme-editor.php')->bottom($files);
|
||||
\Typecho\Plugin::factory('admin/theme-editor.php')->bottom($files);
|
||||
include 'footer.php';
|
||||
?>
|
||||
|
@ -10,50 +10,55 @@ include 'menu.php';
|
||||
<div class="row typecho-page-main" role="main">
|
||||
<div class="col-mb-12">
|
||||
<ul class="typecho-option-tabs fix-tabs clearfix">
|
||||
<li class="current"><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
|
||||
<li class="current"><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a>
|
||||
</li>
|
||||
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?>
|
||||
<li><a href="<?php $options->adminUrl('theme-editor.php'); ?>"><?php _e('编辑当前外观'); ?></a></li>
|
||||
<li><a href="<?php $options->adminUrl('theme-editor.php'); ?>"><?php _e('编辑当前外观'); ?></a></li>
|
||||
<?php endif; ?>
|
||||
<?php if (Widget_Themes_Config::isExists()): ?>
|
||||
<li><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
|
||||
<?php if (\Widget\Themes\Config::isExists()): ?>
|
||||
<li><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="typecho-table-wrap">
|
||||
<table class="typecho-list-table typecho-theme-list">
|
||||
<colgroup>
|
||||
<col width="35%" />
|
||||
<col />
|
||||
<col width="35%"/>
|
||||
<col/>
|
||||
</colgroup>
|
||||
|
||||
|
||||
<thead>
|
||||
<th><?php _e('截图'); ?></th>
|
||||
<th><?php _e('详情'); ?></th>
|
||||
<th><?php _e('截图'); ?></th>
|
||||
<th><?php _e('详情'); ?></th>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<?php Typecho_Widget::widget('Widget_Themes_List')->to($themes); ?>
|
||||
<?php while($themes->next()): ?>
|
||||
<tr id="theme-<?php $themes->name(); ?>" class="<?php if($themes->activated): ?>current<?php endif; ?>">
|
||||
<td valign="top"><img src="<?php $themes->screen(); ?>" alt="<?php $themes->name(); ?>" /></td>
|
||||
<?php \Widget\Themes\Rows::alloc()->to($themes); ?>
|
||||
<?php while ($themes->next()): ?>
|
||||
<tr id="theme-<?php $themes->name(); ?>"
|
||||
class="<?php if ($themes->activated): ?>current<?php endif; ?>">
|
||||
<td valign="top"><img src="<?php $themes->screen(); ?>"
|
||||
alt="<?php $themes->name(); ?>"/></td>
|
||||
<td valign="top">
|
||||
<h3><?php '' != $themes->title ? $themes->title() : $themes->name(); ?></h3>
|
||||
<cite>
|
||||
<?php if($themes->author): ?><?php _e('作者'); ?>: <?php if($themes->homepage): ?><a href="<?php $themes->homepage() ?>"><?php endif; ?><?php $themes->author(); ?><?php if($themes->homepage): ?></a><?php endif; ?> <?php endif; ?>
|
||||
<?php if($themes->version): ?><?php _e('版本'); ?>: <?php $themes->version() ?><?php endif; ?>
|
||||
<?php if ($themes->author): ?><?php _e('作者'); ?>: <?php if ($themes->homepage): ?><a href="<?php $themes->homepage() ?>"><?php endif; ?><?php $themes->author(); ?><?php if ($themes->homepage): ?></a><?php endif; ?> <?php endif; ?>
|
||||
<?php if ($themes->version): ?><?php _e('版本'); ?>: <?php $themes->version() ?><?php endif; ?>
|
||||
</cite>
|
||||
<p><?php echo nl2br($themes->description); ?></p>
|
||||
<?php if($options->theme != $themes->name): ?>
|
||||
<?php if ($options->theme != $themes->name): ?>
|
||||
<p>
|
||||
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?>
|
||||
<a class="edit" href="<?php $options->adminUrl('theme-editor.php?theme=' . $themes->name); ?>"><?php _e('编辑'); ?></a>
|
||||
<a class="edit"
|
||||
href="<?php $options->adminUrl('theme-editor.php?theme=' . $themes->name); ?>"><?php _e('编辑'); ?></a>
|
||||
<?php endif; ?>
|
||||
<a class="activate" href="<?php $security->index('/action/themes-edit?change=' . $themes->name); ?>"><?php _e('启用'); ?></a>
|
||||
<a class="activate"
|
||||
href="<?php $security->index('/action/themes-edit?change=' . $themes->name); ?>"><?php _e('启用'); ?></a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -2,8 +2,6 @@
|
||||
include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
|
||||
$errors = $security->systemCheck();
|
||||
?>
|
||||
|
||||
<div class="main">
|
||||
@ -12,29 +10,21 @@ $errors = $security->systemCheck();
|
||||
<div class="row typecho-page-main" role="main">
|
||||
<div class="col-mb-12">
|
||||
<div id="typecho-welcome">
|
||||
<?php if (!empty($errors)): ?>
|
||||
<form action="<?php echo Typecho_Common::url('upgrade.php', $options->adminUrl); ?>" method="get">
|
||||
<h3><?php _e('发现安全问题'); ?></h3>
|
||||
<ul>
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<li class="warning"><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<p><button class="btn primary" type="submit"><?php _e('解决完毕 »'); ?></button></p>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<form action="<?php echo $security->getTokenUrl(
|
||||
Typecho_Router::url('do', array('action' => 'upgrade', 'widget' => 'Upgrade'),
|
||||
Typecho_Common::url('index.php', $options->rootUrl))); ?>" method="post">
|
||||
<h3><?php _e('检测到新版本!'); ?></h3>
|
||||
<ul>
|
||||
<li><?php _e('您已经更新了系统程序, 我们还需要执行一些后续步骤来完成升级'); ?></li>
|
||||
<li><?php _e('此程序将把您的系统从 <strong>%s</strong> 升级到 <strong>%s</strong>', $options->version, Typecho_Common::VERSION); ?></li>
|
||||
<li><strong class="warning"><?php _e('在升级之前强烈建议先<a href="%s">备份您的数据</a>', Typecho_Common::url('backup.php', $options->adminUrl)); ?></strong></li>
|
||||
</ul>
|
||||
<p><button class="btn primary" type="submit"><?php _e('完成升级 »'); ?></button></p>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<form action="<?php echo $security->getTokenUrl(
|
||||
\Typecho\Router::url('do', ['action' => 'upgrade', 'widget' => 'Upgrade'],
|
||||
\Typecho\Common::url('index.php', $options->rootUrl))); ?>" method="post">
|
||||
<h3><?php _e('检测到新版本!'); ?></h3>
|
||||
<ul>
|
||||
<li><?php _e('您已经更新了系统程序, 我们还需要执行一些后续步骤来完成升级'); ?></li>
|
||||
<li><?php _e('此程序将把您的系统从 <strong>%s</strong> 升级到 <strong>%s</strong>', $options->version, \Typecho\Common::VERSION); ?></li>
|
||||
<li><strong
|
||||
class="warning"><?php _e('在升级之前强烈建议先<a href="%s">备份您的数据</a>', \Typecho\Common::url('backup.php', $options->adminUrl)); ?></strong>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<button class="btn primary" type="submit"><?php _e('完成升级 »'); ?></button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -46,10 +36,10 @@ include 'copyright.php';
|
||||
include 'common-js.php';
|
||||
?>
|
||||
<script>
|
||||
(function () {
|
||||
if (window.sessionStorage) {
|
||||
sessionStorage.removeItem('update');
|
||||
}
|
||||
})();
|
||||
(function () {
|
||||
if (window.sessionStorage) {
|
||||
sessionStorage.removeItem('update');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<?php include 'footer.php'; ?>
|
||||
|
@ -9,7 +9,7 @@ include 'menu.php';
|
||||
<?php include 'page-title.php'; ?>
|
||||
<div class="row typecho-page-main" role="form">
|
||||
<div class="col-mb-12 col-tb-6 col-tb-offset-3">
|
||||
<?php Typecho_Widget::widget('Widget_Users_Edit')->form()->render(); ?>
|
||||
<?php \Widget\Users\Edit::alloc()->form()->render(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
|
||||
<?php Typecho_Plugin::factory('admin/write-js.php')->write(); ?>
|
||||
<?php Typecho_Widget::widget('Widget_Metas_Tag_Cloud', 'sort=count&desc=1&limit=200')->to($tags); ?>
|
||||
<?php \Typecho\Plugin::factory('admin/write-js.php')->write(); ?>
|
||||
<?php \Widget\Metas\Tag\Cloud::alloc('sort=count&desc=1&limit=200')->to($tags); ?>
|
||||
|
||||
<script src="<?php $options->adminStaticUrl('js', 'timepicker.js'); ?>"></script>
|
||||
<script src="<?php $options->adminStaticUrl('js', 'tokeninput.js'); ?>"></script>
|
||||
@ -67,7 +67,7 @@ $(document).ready(function() {
|
||||
'tags' => $tags->name
|
||||
);
|
||||
}
|
||||
echo Json::encode($data);
|
||||
echo json_encode($data);
|
||||
?>, {
|
||||
propertyToSearch: 'tags',
|
||||
tokenValue : 'tags',
|
||||
|
@ -2,7 +2,7 @@
|
||||
include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
Typecho_Widget::widget('Widget_Contents_Page_Edit')->to($page);
|
||||
\Widget\Contents\Page\Edit::alloc()->to($page);
|
||||
?>
|
||||
<div class="main">
|
||||
<div class="body container">
|
||||
@ -12,21 +12,23 @@ Typecho_Widget::widget('Widget_Contents_Page_Edit')->to($page);
|
||||
<div class="col-mb-12 col-tb-9" role="main">
|
||||
<?php if ($page->draft): ?>
|
||||
<?php if ($page->draft['cid'] != $page->cid): ?>
|
||||
<?php $pageModifyDate = new Typecho_Date($page->draft['modified']); ?>
|
||||
<cite class="edit-draft-notice"><?php _e('当前正在编辑的是保存于%s的草稿, 你可以<a href="%s">删除它</a>', $pageModifyDate->word(),
|
||||
<?php $pageModifyDate = new \Typecho\Date($page->draft['modified']); ?>
|
||||
<cite
|
||||
class="edit-draft-notice"><?php _e('当前正在编辑的是保存于%s的草稿, 你可以<a href="%s">删除它</a>', $pageModifyDate->word(),
|
||||
$security->getIndex('/action/contents-page-edit?do=deleteDraft&cid=' . $page->cid)); ?></cite>
|
||||
<?php else: ?>
|
||||
<cite class="edit-draft-notice"><?php _e('当前正在编辑的是未发布的草稿'); ?></cite>
|
||||
<?php endif; ?>
|
||||
<input name="draft" type="hidden" value="<?php echo $page->draft['cid'] ?>" />
|
||||
<input name="draft" type="hidden" value="<?php echo $page->draft['cid'] ?>"/>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="title">
|
||||
<label for="title" class="sr-only"><?php _e('标题'); ?></label>
|
||||
<input type="text" id="title" name="title" autocomplete="off" value="<?php $page->title(); ?>" placeholder="<?php _e('标题'); ?>" class="w-100 text title" />
|
||||
<input type="text" id="title" name="title" autocomplete="off" value="<?php $page->title(); ?>"
|
||||
placeholder="<?php _e('标题'); ?>" class="w-100 text title"/>
|
||||
</p>
|
||||
<?php $permalink = Typecho_Common::url($options->routingTable['page']['url'], $options->index);
|
||||
list ($scheme, $permalink) = explode(':', $permalink, 2);
|
||||
<?php $permalink = \Typecho\Common::url($options->routingTable['page']['url'], $options->index);
|
||||
[$scheme, $permalink] = explode(':', $permalink, 2);
|
||||
$permalink = ltrim($permalink, '/');
|
||||
$permalink = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $permalink);
|
||||
if ($page->have()) {
|
||||
@ -40,26 +42,31 @@ Typecho_Widget::widget('Widget_Contents_Page_Edit')->to($page);
|
||||
</p>
|
||||
<p>
|
||||
<label for="text" class="sr-only"><?php _e('页面内容'); ?></label>
|
||||
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text" name="text" class="w-100 mono"><?php echo htmlspecialchars($page->text); ?></textarea>
|
||||
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text"
|
||||
name="text" class="w-100 mono"><?php echo htmlspecialchars($page->text); ?></textarea>
|
||||
</p>
|
||||
|
||||
|
||||
<?php include 'custom-fields.php'; ?>
|
||||
<p class="submit clearfix">
|
||||
<span class="left">
|
||||
<button type="button" id="btn-cancel-preview" class="btn"><i class="i-caret-left"></i> <?php _e('取消预览'); ?></button>
|
||||
<button type="button" id="btn-cancel-preview" class="btn"><i
|
||||
class="i-caret-left"></i> <?php _e('取消预览'); ?></button>
|
||||
</span>
|
||||
<span class="right">
|
||||
<input type="hidden" name="cid" value="<?php $page->cid(); ?>" />
|
||||
<button type="button" id="btn-preview" class="btn"><i class="i-exlink"></i> <?php _e('预览页面'); ?></button>
|
||||
<button type="submit" name="do" value="save" id="btn-save" class="btn"><?php _e('保存草稿'); ?></button>
|
||||
<button type="submit" name="do" value="publish" class="btn primary" id="btn-submit"><?php _e('发布页面'); ?></button>
|
||||
<input type="hidden" name="cid" value="<?php $page->cid(); ?>"/>
|
||||
<button type="button" id="btn-preview" class="btn"><i
|
||||
class="i-exlink"></i> <?php _e('预览页面'); ?></button>
|
||||
<button type="submit" name="do" value="save" id="btn-save"
|
||||
class="btn"><?php _e('保存草稿'); ?></button>
|
||||
<button type="submit" name="do" value="publish" class="btn primary"
|
||||
id="btn-submit"><?php _e('发布页面'); ?></button>
|
||||
<?php if ($options->markdown && (!$page->have() || $page->isMarkdown)): ?>
|
||||
<input type="hidden" name="markdown" value="1" />
|
||||
<input type="hidden" name="markdown" value="1"/>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<?php Typecho_Plugin::factory('admin/write-page.php')->content($page); ?>
|
||||
|
||||
<?php \Typecho\Plugin::factory('admin/write-page.php')->content($page); ?>
|
||||
</div>
|
||||
<div id="edit-secondary" class="col-mb-12 col-tb-3" role="complementary">
|
||||
<ul class="typecho-option-tabs clearfix">
|
||||
@ -68,68 +75,80 @@ Typecho_Widget::widget('Widget_Contents_Page_Edit')->to($page);
|
||||
</ul>
|
||||
|
||||
<div id="tab-advance" class="tab-content">
|
||||
<section class="typecho-post-option" role="application">
|
||||
<section class="typecho-post-option" role="application">
|
||||
<label for="date" class="typecho-label"><?php _e('发布日期'); ?></label>
|
||||
<p><input class="typecho-date w-100" type="text" name="date" id="date" autocomplete="off" value="<?php $page->have() && $page->created > 0 ? $page->date('Y-m-d H:i') : ''; ?>" /></p>
|
||||
<p><input class="typecho-date w-100" type="text" name="date" id="date" autocomplete="off"
|
||||
value="<?php $page->have() && $page->created > 0 ? $page->date('Y-m-d H:i') : ''; ?>"/>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="typecho-post-option">
|
||||
<label for="order" class="typecho-label"><?php _e('页面顺序'); ?></label>
|
||||
<p><input type="text" id="order" name="order" value="<?php $page->order(); ?>" class="w-100" /></p>
|
||||
<p><input type="text" id="order" name="order" value="<?php $page->order(); ?>"
|
||||
class="w-100"/></p>
|
||||
<p class="description"><?php _e('为你的自定义页面设定一个序列值以后, 能够使得它们按此值从小到大排列'); ?></p>
|
||||
</section>
|
||||
|
||||
<section class="typecho-post-option">
|
||||
<section class="typecho-post-option">
|
||||
<label for="template" class="typecho-label"><?php _e('自定义模板'); ?></label>
|
||||
<p>
|
||||
<select name="template" id="template">
|
||||
<option value=""><?php _e('不选择'); ?></option>
|
||||
<?php $templates = $page->getTemplates(); foreach ($templates as $template => $name): ?>
|
||||
<option value="<?php echo $template; ?>"<?php if($template == $page->template): ?> selected="true"<?php endif; ?>><?php echo $name; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</p>
|
||||
<p class="description"><?php _e('如果你为此页面选择了一个自定义模板, 系统将按照你选择的模板文件展现它'); ?></p>
|
||||
<p>
|
||||
<select name="template" id="template">
|
||||
<option value=""><?php _e('不选择'); ?></option>
|
||||
<?php $templates = $page->getTemplates();
|
||||
foreach ($templates as $template => $name): ?>
|
||||
<option
|
||||
value="<?php echo $template; ?>"<?php if ($template == $page->template): ?> selected="true"<?php endif; ?>><?php echo $name; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</p>
|
||||
<p class="description"><?php _e('如果你为此页面选择了一个自定义模板, 系统将按照你选择的模板文件展现它'); ?></p>
|
||||
</section>
|
||||
|
||||
<?php Typecho_Plugin::factory('admin/write-page.php')->option($page); ?>
|
||||
<?php \Typecho\Plugin::factory('admin/write-page.php')->option($page); ?>
|
||||
|
||||
<button type="button" id="advance-panel-btn" class="btn btn-xs"><?php _e('高级选项'); ?> <i class="i-caret-down"></i></button>
|
||||
<button type="button" id="advance-panel-btn" class="btn btn-xs"><?php _e('高级选项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<div id="advance-panel">
|
||||
<section class="typecho-post-option visibility-option">
|
||||
<label for="visibility" class="typecho-label"><?php _e('公开度'); ?></label>
|
||||
<p>
|
||||
<select id="visibility" name="visibility">
|
||||
<option value="publish"<?php if ($page->status == 'publish' || !$page->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
|
||||
<option value="hidden"<?php if ($page->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
|
||||
</select>
|
||||
<select id="visibility" name="visibility">
|
||||
<option
|
||||
value="publish"<?php if ($page->status == 'publish' || !$page->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
|
||||
<option
|
||||
value="hidden"<?php if ($page->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
|
||||
</select>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="typecho-post-option allow-option">
|
||||
<label class="typecho-label"><?php _e('权限控制'); ?></label>
|
||||
<ul>
|
||||
<li><input id="allowComment" name="allowComment" type="checkbox" value="1" <?php if($page->allow('comment')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowComment"><?php _e('允许评论'); ?></label></li>
|
||||
<li><input id="allowPing" name="allowPing" type="checkbox" value="1" <?php if($page->allow('ping')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowPing"><?php _e('允许被引用'); ?></label></li>
|
||||
<li><input id="allowFeed" name="allowFeed" type="checkbox" value="1" <?php if($page->allow('feed')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowFeed"><?php _e('允许在聚合中出现'); ?></label></li>
|
||||
<li><input id="allowComment" name="allowComment" type="checkbox" value="1"
|
||||
<?php if ($page->allow('comment')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowComment"><?php _e('允许评论'); ?></label></li>
|
||||
<li><input id="allowPing" name="allowPing" type="checkbox" value="1"
|
||||
<?php if ($page->allow('ping')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowPing"><?php _e('允许被引用'); ?></label></li>
|
||||
<li><input id="allowFeed" name="allowFeed" type="checkbox" value="1"
|
||||
<?php if ($page->allow('feed')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowFeed"><?php _e('允许在聚合中出现'); ?></label></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<?php Typecho_Plugin::factory('admin/write-page.php')->advanceOption($page); ?>
|
||||
|
||||
<?php \Typecho\Plugin::factory('admin/write-page.php')->advanceOption($page); ?>
|
||||
</div>
|
||||
<?php if($page->have()): ?>
|
||||
<?php $modified = new Typecho_Date($page->modified); ?>
|
||||
<section class="typecho-post-option">
|
||||
<p class="description">
|
||||
<br>—<br>
|
||||
<?php _e('本页面由 <a href="%s">%s</a> 创建',
|
||||
Typecho_Common::url('manage-pages.php?uid=' . $page->author->uid, $options->adminUrl), $page->author->screenName); ?><br>
|
||||
<?php _e('最后更新于 %s', $modified->word()); ?>
|
||||
</p>
|
||||
</section>
|
||||
<?php if ($page->have()): ?>
|
||||
<?php $modified = new \Typecho\Date($page->modified); ?>
|
||||
<section class="typecho-post-option">
|
||||
<p class="description">
|
||||
<br>—<br>
|
||||
<?php _e('本页面由 <a href="%s">%s</a> 创建',
|
||||
\Typecho\Common::url('manage-pages.php?uid=' . $page->author->uid, $options->adminUrl), $page->author->screenName); ?>
|
||||
<br>
|
||||
<?php _e('最后更新于 %s', $modified->word()); ?>
|
||||
</p>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</div><!-- end #tab-advance -->
|
||||
|
||||
@ -148,13 +167,13 @@ include 'common-js.php';
|
||||
include 'form-js.php';
|
||||
include 'write-js.php';
|
||||
|
||||
Typecho_Plugin::factory('admin/write-page.php')->trigger($plugged)->richEditor($page);
|
||||
\Typecho\Plugin::factory('admin/write-page.php')->trigger($plugged)->richEditor($page);
|
||||
if (!$plugged) {
|
||||
include 'editor-js.php';
|
||||
}
|
||||
|
||||
include 'file-upload-js.php';
|
||||
include 'custom-fields-js.php';
|
||||
Typecho_Plugin::factory('admin/write-page.php')->bottom($page);
|
||||
\Typecho\Plugin::factory('admin/write-page.php')->bottom($page);
|
||||
include 'footer.php';
|
||||
?>
|
||||
|
@ -2,7 +2,7 @@
|
||||
include 'common.php';
|
||||
include 'header.php';
|
||||
include 'menu.php';
|
||||
Typecho_Widget::widget('Widget_Contents_Post_Edit')->to($post);
|
||||
\Widget\Contents\Post\Edit::alloc()->to($post);
|
||||
?>
|
||||
<div class="main">
|
||||
<div class="body container">
|
||||
@ -12,29 +12,31 @@ Typecho_Widget::widget('Widget_Contents_Post_Edit')->to($post);
|
||||
<div class="col-mb-12 col-tb-9" role="main">
|
||||
<?php if ($post->draft): ?>
|
||||
<?php if ($post->draft['cid'] != $post->cid): ?>
|
||||
<?php $postModifyDate = new Typecho_Date($post->draft['modified']); ?>
|
||||
<cite class="edit-draft-notice"><?php _e('你正在编辑的是保存于 %s 的草稿, 你也可以 <a href="%s">删除它</a>', $postModifyDate->word(),
|
||||
<?php $postModifyDate = new \Typecho\Date($post->draft['modified']); ?>
|
||||
<cite
|
||||
class="edit-draft-notice"><?php _e('你正在编辑的是保存于 %s 的草稿, 你也可以 <a href="%s">删除它</a>', $postModifyDate->word(),
|
||||
$security->getIndex('/action/contents-post-edit?do=deleteDraft&cid=' . $post->cid)); ?></cite>
|
||||
<?php else: ?>
|
||||
<cite class="edit-draft-notice"><?php _e('当前正在编辑的是未发布的草稿'); ?></cite>
|
||||
<?php endif; ?>
|
||||
<input name="draft" type="hidden" value="<?php echo $post->draft['cid'] ?>" />
|
||||
<input name="draft" type="hidden" value="<?php echo $post->draft['cid'] ?>"/>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="title">
|
||||
<label for="title" class="sr-only"><?php _e('标题'); ?></label>
|
||||
<input type="text" id="title" name="title" autocomplete="off" value="<?php $post->title(); ?>" placeholder="<?php _e('标题'); ?>" class="w-100 text title" />
|
||||
<input type="text" id="title" name="title" autocomplete="off" value="<?php $post->title(); ?>"
|
||||
placeholder="<?php _e('标题'); ?>" class="w-100 text title"/>
|
||||
</p>
|
||||
<?php $permalink = Typecho_Common::url($options->routingTable['post']['url'], $options->index);
|
||||
list ($scheme, $permalink) = explode(':', $permalink, 2);
|
||||
<?php $permalink = \Typecho\Common::url($options->routingTable['post']['url'], $options->index);
|
||||
[$scheme, $permalink] = explode(':', $permalink, 2);
|
||||
$permalink = ltrim($permalink, '/');
|
||||
$permalink = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $permalink);
|
||||
if ($post->have()) {
|
||||
$permalink = str_replace(array(
|
||||
$permalink = str_replace([
|
||||
'{cid}', '{category}', '{year}', '{month}', '{day}'
|
||||
), array(
|
||||
], [
|
||||
$post->cid, $post->category, $post->year, $post->month, $post->day
|
||||
), $permalink);
|
||||
], $permalink);
|
||||
}
|
||||
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($post->slug) . '" class="mono" />';
|
||||
?>
|
||||
@ -44,27 +46,32 @@ Typecho_Widget::widget('Widget_Contents_Post_Edit')->to($post);
|
||||
</p>
|
||||
<p>
|
||||
<label for="text" class="sr-only"><?php _e('文章内容'); ?></label>
|
||||
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text" name="text" class="w-100 mono"><?php echo htmlspecialchars($post->text); ?></textarea>
|
||||
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text"
|
||||
name="text" class="w-100 mono"><?php echo htmlspecialchars($post->text); ?></textarea>
|
||||
</p>
|
||||
|
||||
|
||||
<?php include 'custom-fields.php'; ?>
|
||||
|
||||
<p class="submit clearfix">
|
||||
<span class="left">
|
||||
<button type="button" id="btn-cancel-preview" class="btn"><i class="i-caret-left"></i> <?php _e('取消预览'); ?></button>
|
||||
<button type="button" id="btn-cancel-preview" class="btn"><i
|
||||
class="i-caret-left"></i> <?php _e('取消预览'); ?></button>
|
||||
</span>
|
||||
<span class="right">
|
||||
<input type="hidden" name="cid" value="<?php $post->cid(); ?>" />
|
||||
<button type="button" id="btn-preview" class="btn"><i class="i-exlink"></i> <?php _e('预览文章'); ?></button>
|
||||
<button type="submit" name="do" value="save" id="btn-save" class="btn"><?php _e('保存草稿'); ?></button>
|
||||
<button type="submit" name="do" value="publish" class="btn primary" id="btn-submit"><?php _e('发布文章'); ?></button>
|
||||
<input type="hidden" name="cid" value="<?php $post->cid(); ?>"/>
|
||||
<button type="button" id="btn-preview" class="btn"><i
|
||||
class="i-exlink"></i> <?php _e('预览文章'); ?></button>
|
||||
<button type="submit" name="do" value="save" id="btn-save"
|
||||
class="btn"><?php _e('保存草稿'); ?></button>
|
||||
<button type="submit" name="do" value="publish" class="btn primary"
|
||||
id="btn-submit"><?php _e('发布文章'); ?></button>
|
||||
<?php if ($options->markdown && (!$post->have() || $post->isMarkdown)): ?>
|
||||
<input type="hidden" name="markdown" value="1" />
|
||||
<input type="hidden" name="markdown" value="1"/>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<?php Typecho_Plugin::factory('admin/write-post.php')->content($post); ?>
|
||||
<?php \Typecho\Plugin::factory('admin/write-post.php')->content($post); ?>
|
||||
</div>
|
||||
|
||||
<div id="edit-secondary" class="col-mb-12 col-tb-3" role="complementary">
|
||||
@ -77,88 +84,108 @@ Typecho_Widget::widget('Widget_Contents_Post_Edit')->to($post);
|
||||
<div id="tab-advance" class="tab-content">
|
||||
<section class="typecho-post-option" role="application">
|
||||
<label for="date" class="typecho-label"><?php _e('发布日期'); ?></label>
|
||||
<p><input class="typecho-date w-100" type="text" name="date" id="date" autocomplete="off" value="<?php $post->have() && $post->created > 0 ? $post->date('Y-m-d H:i') : ''; ?>" /></p>
|
||||
<p><input class="typecho-date w-100" type="text" name="date" id="date" autocomplete="off"
|
||||
value="<?php $post->have() && $post->created > 0 ? $post->date('Y-m-d H:i') : ''; ?>"/>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="typecho-post-option category-option">
|
||||
<label class="typecho-label"><?php _e('分类'); ?></label>
|
||||
<?php Typecho_Widget::widget('Widget_Metas_Category_List')->to($category); ?>
|
||||
<?php \Widget\Metas\Category\Rows::alloc()->to($category); ?>
|
||||
<ul>
|
||||
<?php
|
||||
if ($post->have()) {
|
||||
$categories = Typecho_Common::arrayFlatten($post->categories, 'mid');
|
||||
$categories = array_column($post->categories, 'mid');
|
||||
} else {
|
||||
$categories = array();
|
||||
$categories = [];
|
||||
}
|
||||
?>
|
||||
<?php while($category->next()): ?>
|
||||
<li><?php echo str_repeat(' ', $category->levels); ?><input type="checkbox" id="category-<?php $category->mid(); ?>" value="<?php $category->mid(); ?>" name="category[]" <?php if(in_array($category->mid, $categories)): ?>checked="true"<?php endif; ?>/>
|
||||
<label for="category-<?php $category->mid(); ?>"><?php $category->name(); ?></label></li>
|
||||
<?php while ($category->next()): ?>
|
||||
<li><?php echo str_repeat(' ', $category->levels); ?><input
|
||||
type="checkbox" id="category-<?php $category->mid(); ?>"
|
||||
value="<?php $category->mid(); ?>" name="category[]"
|
||||
<?php if (in_array($category->mid, $categories)): ?>checked="true"<?php endif; ?>/>
|
||||
<label
|
||||
for="category-<?php $category->mid(); ?>"><?php $category->name(); ?></label>
|
||||
</li>
|
||||
<?php endwhile; ?>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="typecho-post-option">
|
||||
<label for="token-input-tags" class="typecho-label"><?php _e('标签'); ?></label>
|
||||
<p><input id="tags" name="tags" type="text" value="<?php $post->tags(',', false); ?>" class="w-100 text" /></p>
|
||||
<p><input id="tags" name="tags" type="text" value="<?php $post->tags(',', false); ?>"
|
||||
class="w-100 text"/></p>
|
||||
</section>
|
||||
|
||||
<?php Typecho_Plugin::factory('admin/write-post.php')->option($post); ?>
|
||||
<?php \Typecho\Plugin::factory('admin/write-post.php')->option($post); ?>
|
||||
|
||||
<button type="button" id="advance-panel-btn" class="btn btn-xs"><?php _e('高级选项'); ?> <i class="i-caret-down"></i></button>
|
||||
<button type="button" id="advance-panel-btn" class="btn btn-xs"><?php _e('高级选项'); ?> <i
|
||||
class="i-caret-down"></i></button>
|
||||
<div id="advance-panel">
|
||||
<?php if($user->pass('editor', true)): ?>
|
||||
<section class="typecho-post-option visibility-option">
|
||||
<label for="visibility" class="typecho-label"><?php _e('公开度'); ?></label>
|
||||
<p>
|
||||
<select id="visibility" name="visibility">
|
||||
<?php if ($user->pass('editor', true)): ?>
|
||||
<option value="publish"<?php if (($post->status == 'publish' && !$post->password) || !$post->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
|
||||
<option value="hidden"<?php if ($post->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
|
||||
<option value="password"<?php if (strlen($post->password) > 0): ?> selected<?php endif; ?>><?php _e('密码保护'); ?></option>
|
||||
<option value="private"<?php if ($post->status == 'private'): ?> selected<?php endif; ?>><?php _e('私密'); ?></option>
|
||||
<?php endif; ?>
|
||||
<option value="waiting"<?php if (!$user->pass('editor', true) || $post->status == 'waiting'): ?> selected<?php endif; ?>><?php _e('待审核'); ?></option>
|
||||
</select>
|
||||
</p>
|
||||
<p id="post-password"<?php if (strlen($post->password) == 0): ?> class="hidden"<?php endif; ?>>
|
||||
<label for="protect-pwd" class="sr-only">内容密码</label>
|
||||
<input type="text" name="password" id="protect-pwd" class="text-s" value="<?php $post->password(); ?>" size="16" placeholder="<?php _e('内容密码'); ?>" autocomplete="off" />
|
||||
</p>
|
||||
</section>
|
||||
<?php if ($user->pass('editor', true)): ?>
|
||||
<section class="typecho-post-option visibility-option">
|
||||
<label for="visibility" class="typecho-label"><?php _e('公开度'); ?></label>
|
||||
<p>
|
||||
<select id="visibility" name="visibility">
|
||||
<?php if ($user->pass('editor', true)): ?>
|
||||
<option
|
||||
value="publish"<?php if (($post->status == 'publish' && !$post->password) || !$post->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
|
||||
<option
|
||||
value="hidden"<?php if ($post->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
|
||||
<option
|
||||
value="password"<?php if (strlen($post->password) > 0): ?> selected<?php endif; ?>><?php _e('密码保护'); ?></option>
|
||||
<option
|
||||
value="private"<?php if ($post->status == 'private'): ?> selected<?php endif; ?>><?php _e('私密'); ?></option>
|
||||
<?php endif; ?>
|
||||
<option
|
||||
value="waiting"<?php if (!$user->pass('editor', true) || $post->status == 'waiting'): ?> selected<?php endif; ?>><?php _e('待审核'); ?></option>
|
||||
</select>
|
||||
</p>
|
||||
<p id="post-password"<?php if (strlen($post->password) == 0): ?> class="hidden"<?php endif; ?>>
|
||||
<label for="protect-pwd" class="sr-only">内容密码</label>
|
||||
<input type="text" name="password" id="protect-pwd" class="text-s"
|
||||
value="<?php $post->password(); ?>" size="16"
|
||||
placeholder="<?php _e('内容密码'); ?>" autocomplete="off"/>
|
||||
</p>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<section class="typecho-post-option allow-option">
|
||||
<label class="typecho-label"><?php _e('权限控制'); ?></label>
|
||||
<ul>
|
||||
<li><input id="allowComment" name="allowComment" type="checkbox" value="1" <?php if($post->allow('comment')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowComment"><?php _e('允许评论'); ?></label></li>
|
||||
<li><input id="allowPing" name="allowPing" type="checkbox" value="1" <?php if($post->allow('ping')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowPing"><?php _e('允许被引用'); ?></label></li>
|
||||
<li><input id="allowFeed" name="allowFeed" type="checkbox" value="1" <?php if($post->allow('feed')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowFeed"><?php _e('允许在聚合中出现'); ?></label></li>
|
||||
<li><input id="allowComment" name="allowComment" type="checkbox" value="1"
|
||||
<?php if ($post->allow('comment')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowComment"><?php _e('允许评论'); ?></label></li>
|
||||
<li><input id="allowPing" name="allowPing" type="checkbox" value="1"
|
||||
<?php if ($post->allow('ping')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowPing"><?php _e('允许被引用'); ?></label></li>
|
||||
<li><input id="allowFeed" name="allowFeed" type="checkbox" value="1"
|
||||
<?php if ($post->allow('feed')): ?>checked="true"<?php endif; ?> />
|
||||
<label for="allowFeed"><?php _e('允许在聚合中出现'); ?></label></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="typecho-post-option">
|
||||
<label for="trackback" class="typecho-label"><?php _e('引用通告'); ?></label>
|
||||
<p><textarea id="trackback" class="w-100 mono" name="trackback" rows="2"></textarea></p>
|
||||
<p class="description"><?php _e('每一行一个引用地址, 用回车隔开'); ?></p>
|
||||
</section>
|
||||
|
||||
<?php Typecho_Plugin::factory('admin/write-post.php')->advanceOption($post); ?>
|
||||
<?php \Typecho\Plugin::factory('admin/write-post.php')->advanceOption($post); ?>
|
||||
</div><!-- end #advance-panel -->
|
||||
|
||||
<?php if($post->have()): ?>
|
||||
<?php $modified = new Typecho_Date($post->modified); ?>
|
||||
<section class="typecho-post-option">
|
||||
<p class="description">
|
||||
<br>—<br>
|
||||
<?php _e('本文由 <a href="%s">%s</a> 撰写',
|
||||
Typecho_Common::url('manage-posts.php?uid=' . $post->author->uid, $options->adminUrl), $post->author->screenName); ?><br>
|
||||
<?php _e('最后更新于 %s', $modified->word()); ?>
|
||||
</p>
|
||||
</section>
|
||||
<?php if ($post->have()): ?>
|
||||
<?php $modified = new \Typecho\Date($post->modified); ?>
|
||||
<section class="typecho-post-option">
|
||||
<p class="description">
|
||||
<br>—<br>
|
||||
<?php _e('本文由 <a href="%s">%s</a> 撰写',
|
||||
\Typecho\Common::url('manage-posts.php?uid=' . $post->author->uid, $options->adminUrl), $post->author->screenName); ?>
|
||||
<br>
|
||||
<?php _e('最后更新于 %s', $modified->word()); ?>
|
||||
</p>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</div><!-- end #tab-advance -->
|
||||
|
||||
@ -177,13 +204,13 @@ include 'common-js.php';
|
||||
include 'form-js.php';
|
||||
include 'write-js.php';
|
||||
|
||||
Typecho_Plugin::factory('admin/write-post.php')->trigger($plugged)->richEditor($post);
|
||||
\Typecho\Plugin::factory('admin/write-post.php')->trigger($plugged)->richEditor($post);
|
||||
if (!$plugged) {
|
||||
include 'editor-js.php';
|
||||
}
|
||||
|
||||
include 'file-upload-js.php';
|
||||
include 'custom-fields-js.php';
|
||||
Typecho_Plugin::factory('admin/write-post.php')->bottom($post);
|
||||
\Typecho\Plugin::factory('admin/write-post.php')->bottom($post);
|
||||
include 'footer.php';
|
||||
?>
|
||||
|
@ -14,13 +14,13 @@ if (!defined('__TYPECHO_ROOT_DIR__') && !@include_once 'config.inc.php') {
|
||||
}
|
||||
|
||||
/** 初始化组件 */
|
||||
Typecho_Widget::widget('Widget_Init');
|
||||
\Widget\Init::alloc();
|
||||
|
||||
/** 注册一个初始化插件 */
|
||||
Typecho_Plugin::factory('index.php')->begin();
|
||||
\Typecho\Plugin::factory('index.php')->begin();
|
||||
|
||||
/** 开始路由分发 */
|
||||
Typecho_Router::dispatch();
|
||||
\Typecho\Router::dispatch();
|
||||
|
||||
/** 注册一个结束插件 */
|
||||
Typecho_Plugin::factory('index.php')->end();
|
||||
\Typecho\Plugin::factory('index.php')->end();
|
||||
|
566
install.php
566
install.php
@ -1,58 +1,49 @@
|
||||
<?php if (!file_exists(dirname(__FILE__) . '/config.inc.php')): ?>
|
||||
<?php
|
||||
/**
|
||||
* Typecho Blog Platform
|
||||
*
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
// site root path
|
||||
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));
|
||||
if (!file_exists(dirname(__FILE__) . '/config.inc.php')) {
|
||||
// site root path
|
||||
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));
|
||||
|
||||
// plugin directory (relative path)
|
||||
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');
|
||||
// plugin directory (relative path)
|
||||
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');
|
||||
|
||||
// theme directory (relative path)
|
||||
define('__TYPECHO_THEME_DIR__', '/usr/themes');
|
||||
// theme directory (relative path)
|
||||
define('__TYPECHO_THEME_DIR__', '/usr/themes');
|
||||
|
||||
// admin directory (relative path)
|
||||
define('__TYPECHO_ADMIN_DIR__', '/admin/');
|
||||
// admin directory (relative path)
|
||||
define('__TYPECHO_ADMIN_DIR__', '/admin/');
|
||||
|
||||
// register autoload
|
||||
require_once __TYPECHO_ROOT_DIR__ . '/var/Typecho/Common.php';
|
||||
|
||||
// init
|
||||
Typecho_Common::init();
|
||||
|
||||
else:
|
||||
// register autoload
|
||||
require_once __TYPECHO_ROOT_DIR__ . '/var/Typecho/Common.php';
|
||||
|
||||
// init
|
||||
\Typecho\Common::init();
|
||||
} else {
|
||||
require_once dirname(__FILE__) . '/config.inc.php';
|
||||
$installDb = Typecho_Db::get();
|
||||
|
||||
endif;
|
||||
$installDb = \Typecho\Db::get();
|
||||
}
|
||||
|
||||
/**
|
||||
* get lang
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function install_get_lang(): string {
|
||||
$serverLang = Typecho_Request::getInstance()->getServer('TYPECHO_LANG');
|
||||
function install_get_lang(): string
|
||||
{
|
||||
$serverLang = \Typecho\Request::getInstance()->getServer('TYPECHO_LANG');
|
||||
|
||||
if (!empty($serverLang)) {
|
||||
return $serverLang;
|
||||
} else {
|
||||
$lang = 'zh_CN';
|
||||
$request = Typecho_Request::getInstance();
|
||||
$request = \Typecho\Request::getInstance();
|
||||
|
||||
if ($request->is('lang')) {
|
||||
$lang = $request->get('lang');
|
||||
Typecho_Cookie::set('lang', $lang);
|
||||
\Typecho\Cookie::set('lang', $lang);
|
||||
}
|
||||
|
||||
return Typecho_Cookie::get('lang', $lang);
|
||||
return \Typecho\Cookie::get('lang', $lang);
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,8 +52,9 @@ function install_get_lang(): string {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function install_get_site_url(): string {
|
||||
$serverSiteUrl = Typecho_Request::getInstance()->getServer(
|
||||
function install_get_site_url(): string
|
||||
{
|
||||
$serverSiteUrl = \Typecho\Request::getInstance()->getServer(
|
||||
'TYPECHO_SITE_URL',
|
||||
install_is_cli() ? 'http://localhost' : null
|
||||
);
|
||||
@ -70,7 +62,7 @@ function install_get_site_url(): string {
|
||||
if (!empty($serverSiteUrl)) {
|
||||
return $serverSiteUrl;
|
||||
} else {
|
||||
$request = Typecho_Request::getInstance();
|
||||
$request = \Typecho\Request::getInstance();
|
||||
return $request->get('userUrl', $request->getRequestRoot());
|
||||
}
|
||||
}
|
||||
@ -80,8 +72,170 @@ function install_get_site_url(): string {
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function install_is_cli(): bool {
|
||||
return php_sapi_name() == 'cli';
|
||||
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',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,7 +243,8 @@ function install_is_cli(): bool {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function install_get_default_options(): array {
|
||||
function install_get_default_options(): array
|
||||
{
|
||||
static $options;
|
||||
|
||||
if (empty($options)) {
|
||||
@ -98,10 +253,10 @@ function install_get_default_options(): array {
|
||||
'theme:default' => 'a:2:{s:7:"logoUrl";N;s:12:"sidebarBlock";a:5:{i:0;s:15:"ShowRecentPosts";i:1;s:18:"ShowRecentComments";i:2;s:12:"ShowCategory";i:3;s:11:"ShowArchive";i:4;s:9:"ShowOther";}}',
|
||||
'timezone' => '28800',
|
||||
'lang' => install_get_lang(),
|
||||
'charset' => _t('UTF-8'),
|
||||
'charset' => 'UTF-8',
|
||||
'contentType' => 'text/html',
|
||||
'gzip' => 0,
|
||||
'generator' => 'Typecho ' . Typecho_Common::VERSION,
|
||||
'generator' => 'Typecho ' . \Typecho\Common::VERSION,
|
||||
'title' => 'Hello World',
|
||||
'description' => 'Your description here.',
|
||||
'keywords' => 'typecho,php,blog',
|
||||
@ -148,11 +303,11 @@ 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@',
|
||||
'secret' => Typecho_Common::randString(32, true),
|
||||
'secret' => \Typecho\Common::randString(32, true),
|
||||
'installed' => 0,
|
||||
'allowXmlRpc' => 2
|
||||
];
|
||||
@ -167,7 +322,8 @@ function install_get_default_options(): array {
|
||||
* @param string $driver
|
||||
* @return string
|
||||
*/
|
||||
function install_get_db_type(string $driver): string {
|
||||
function install_get_db_type(string $driver): string
|
||||
{
|
||||
$parts = explode('_', $driver);
|
||||
return $driver == 'Mysqli' ? 'Mysql' : array_pop($parts);
|
||||
}
|
||||
@ -177,30 +333,31 @@ function install_get_db_type(string $driver): string {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function install_get_db_drivers(): array {
|
||||
function install_get_db_drivers(): array
|
||||
{
|
||||
$drivers = [];
|
||||
|
||||
if (Typecho_Db_Adapter_Pdo_Mysql::isAvailable()) {
|
||||
if (\Typecho\Db\Adapter\Pdo\Mysql::isAvailable()) {
|
||||
$drivers['Pdo_Mysql'] = _t('Pdo 驱动 Mysql 适配器');
|
||||
}
|
||||
|
||||
if (Typecho_Db_Adapter_Pdo_SQLite::isAvailable()) {
|
||||
$drivers['Pdo_SQLite'] = _t('Pdo 驱动 SQLite 适配器 (SQLite 3.x)');
|
||||
if (\Typecho\Db\Adapter\Pdo\SQLite::isAvailable()) {
|
||||
$drivers['Pdo_SQLite'] = _t('Pdo 驱动 SQLite 适配器');
|
||||
}
|
||||
|
||||
if (Typecho_Db_Adapter_Pdo_Pgsql::isAvailable()) {
|
||||
if (\Typecho\Db\Adapter\Pdo\Pgsql::isAvailable()) {
|
||||
$drivers['Pdo_Pgsql'] = _t('Pdo 驱动 PostgreSql 适配器');
|
||||
}
|
||||
|
||||
if (Typecho_Db_Adapter_Mysqli::isAvailable()) {
|
||||
if (\Typecho\Db\Adapter\Mysqli::isAvailable()) {
|
||||
$drivers['Mysqli'] = _t('Mysql 原生函数适配器');
|
||||
}
|
||||
|
||||
if (Typecho_Db_Adapter_SQLite::isAvailable()) {
|
||||
$drivers['SQLite'] = _t('SQLite 原生函数适配器 (SQLite 2.x)');
|
||||
if (\Typecho\Db\Adapter\SQLite::isAvailable()) {
|
||||
$drivers['SQLite'] = _t('SQLite 原生函数适配器');
|
||||
}
|
||||
|
||||
if (Typecho_Db_Adapter_Pgsql::isAvailable()) {
|
||||
if (\Typecho\Db\Adapter\Pgsql::isAvailable()) {
|
||||
$drivers['Pgsql'] = _t('Pgsql 原生函数适配器');
|
||||
}
|
||||
|
||||
@ -212,11 +369,12 @@ function install_get_db_drivers(): array {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function install_get_current_db_driver(): string {
|
||||
function install_get_current_db_driver(): string
|
||||
{
|
||||
global $installDb;
|
||||
|
||||
if (empty($installDb)) {
|
||||
$driver = Typecho_Request::getInstance()->get('driver');
|
||||
$driver = \Typecho\Request::getInstance()->get('driver');
|
||||
$drivers = install_get_db_drivers();
|
||||
|
||||
if (empty($driver) || !isset($drivers[$driver])) {
|
||||
@ -238,18 +396,35 @@ function install_get_current_db_driver(): string {
|
||||
* @param bool $return
|
||||
* @return string
|
||||
*/
|
||||
function install_config_file(string $adapter, string $dbPrefix, array $dbConfig, bool $return = false): string {
|
||||
function install_config_file(string $adapter, string $dbPrefix, array $dbConfig, bool $return = false): string
|
||||
{
|
||||
global $configWritten;
|
||||
|
||||
$lines = array_slice(file(__FILE__), 1, 26);
|
||||
$lines[] = "
|
||||
/** 定义数据库参数 */
|
||||
\$db = new Typecho_Db('{$adapter}', '{$dbPrefix}');
|
||||
\$db->addServer(" . (var_export($dbConfig, true)) . ", Typecho_Db::READ | Typecho_Db::WRITE);
|
||||
Typecho_Db::set(\$db);
|
||||
$code = "<" . "?php
|
||||
// site root path
|
||||
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));
|
||||
|
||||
// plugin directory (relative path)
|
||||
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');
|
||||
|
||||
// theme directory (relative path)
|
||||
define('__TYPECHO_THEME_DIR__', '/usr/themes');
|
||||
|
||||
// admin directory (relative path)
|
||||
define('__TYPECHO_ADMIN_DIR__', '/admin/');
|
||||
|
||||
// register autoload
|
||||
require_once __TYPECHO_ROOT_DIR__ . '/var/Typecho/Common.php';
|
||||
|
||||
// init
|
||||
\Typecho\Common::init();
|
||||
|
||||
// config db
|
||||
\$db = new \Typecho\Db('{$adapter}', '{$dbPrefix}');
|
||||
\$db->addServer(" . (var_export($dbConfig, true)) . ", \Typecho\Db::READ | \Typecho\Db::WRITE);
|
||||
\Typecho\Db::set(\$db);
|
||||
";
|
||||
|
||||
$code = implode('', $lines);
|
||||
$configWritten = false;
|
||||
|
||||
if (!$return) {
|
||||
@ -262,7 +437,8 @@ Typecho_Db::set(\$db);
|
||||
/**
|
||||
* remove config file if written
|
||||
*/
|
||||
function install_remove_config_file() {
|
||||
function install_remove_config_file()
|
||||
{
|
||||
global $configWritten;
|
||||
|
||||
if ($configWritten) {
|
||||
@ -276,7 +452,8 @@ function install_remove_config_file() {
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
function install_check(string $type): bool {
|
||||
function install_check(string $type): bool
|
||||
{
|
||||
switch ($type) {
|
||||
case 'config':
|
||||
return file_exists(__TYPECHO_ROOT_DIR__ . '/config.inc.php');
|
||||
@ -296,7 +473,9 @@ function install_check(string $type): bool {
|
||||
if ($type == 'db_data' && empty($values)) {
|
||||
return false;
|
||||
}
|
||||
} catch (Typecho_Db_Exception $e) {
|
||||
} catch (\Typecho\Db\Adapter\ConnectionException $e) {
|
||||
return true;
|
||||
} catch (\Typecho\Db\Adapter\SQLException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -312,7 +491,8 @@ function install_check(string $type): bool {
|
||||
* @param mixed $error
|
||||
* @param mixed $config
|
||||
*/
|
||||
function install_raise_error($error, $config = null) {
|
||||
function install_raise_error($error, $config = null)
|
||||
{
|
||||
if (install_is_cli()) {
|
||||
if (is_array($error)) {
|
||||
foreach ($error as $key => $value) {
|
||||
@ -324,7 +504,7 @@ function install_raise_error($error, $config = null) {
|
||||
|
||||
exit(1);
|
||||
} else {
|
||||
Typecho_Response::getInstance()->throwJson([
|
||||
install_throw_json([
|
||||
'success' => 0,
|
||||
'message' => is_string($error) ? nl2br($error) : $error,
|
||||
'config' => $config
|
||||
@ -336,7 +516,8 @@ function install_raise_error($error, $config = null) {
|
||||
* @param $step
|
||||
* @param array|null $config
|
||||
*/
|
||||
function install_success($step, ?array $config = null) {
|
||||
function install_success($step, ?array $config = null)
|
||||
{
|
||||
if (install_is_cli()) {
|
||||
if ($step > 0) {
|
||||
$method = 'install_step_' . $step . '_perform';
|
||||
@ -352,7 +533,7 @@ function install_success($step, ?array $config = null) {
|
||||
|
||||
exit(0);
|
||||
} else {
|
||||
Typecho_Response::getInstance()->throwJson([
|
||||
install_throw_json([
|
||||
'success' => 1,
|
||||
'message' => $step,
|
||||
'config' => $config
|
||||
@ -361,13 +542,32 @@ function install_success($step, ?array $config = null) {
|
||||
}
|
||||
|
||||
/**
|
||||
* add common js support
|
||||
*
|
||||
* @throws Typecho_Exception
|
||||
* @param $data
|
||||
*/
|
||||
function install_js_support() {
|
||||
$options = Typecho_Widget::widget('Widget_Options');
|
||||
function install_throw_json($data)
|
||||
{
|
||||
\Typecho\Response::getInstance()->setContentType('application/json')
|
||||
->addResponder(function () use ($data) {
|
||||
echo json_encode($data);
|
||||
})
|
||||
->respond();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*/
|
||||
function install_redirect(string $url)
|
||||
{
|
||||
\Typecho\Response::getInstance()->setStatus(302)
|
||||
->setHeader('Location', $url)
|
||||
->respond();
|
||||
}
|
||||
|
||||
/**
|
||||
* add common js support
|
||||
*/
|
||||
function install_js_support()
|
||||
{
|
||||
?>
|
||||
<div id="success" class="row typecho-page-main hidden">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
@ -471,20 +671,37 @@ function install_js_support() {
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
<?php
|
||||
}
|
||||
|
||||
function install_step_1() {
|
||||
$langs = Widget_Options_General::getLangs();
|
||||
/**
|
||||
* @param string[] $extensions
|
||||
* @return string|null
|
||||
*/
|
||||
function install_check_extension(array $extensions): ?string
|
||||
{
|
||||
foreach ($extensions as $extension) {
|
||||
if (extension_loaded($extension)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return _n('缺少PHP扩展', '请在服务器上安装以下PHP扩展中的至少一个', count($extensions))
|
||||
. ': ' . implode(', ', $extensions);
|
||||
}
|
||||
|
||||
function install_step_1()
|
||||
{
|
||||
$langs = \Widget\Options\General::getLangs();
|
||||
$lang = install_get_lang();
|
||||
?>
|
||||
?>
|
||||
<div class="row typecho-page-main">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
<div class="typecho-page-title">
|
||||
<h2><?php _e('欢迎使用 Typecho'); ?></h2>
|
||||
</div>
|
||||
<div id="typecho-welcome">
|
||||
<form autocomplete="off" method="get" action="install.php">
|
||||
<form autocomplete="off" method="post" action="install.php">
|
||||
<h3><?php _e('安装说明'); ?></h3>
|
||||
<p class="warning">
|
||||
<strong><?php _e('本安装程序将自动检测服务器环境是否符合最低配置需求. 如果不符合, 将在上方出现提示信息, 请按照提示信息检查您的主机配置. 如果服务器环境符合要求, 将在下方出现 "开始下一步" 的按钮, 点击此按钮即可一步完成安装.'); ?></strong>
|
||||
@ -500,12 +717,14 @@ function install_step_1() {
|
||||
|
||||
<p class="submit">
|
||||
<button class="btn primary" type="submit"><?php _e('我准备好了, 开始下一步 »'); ?></button>
|
||||
<input type="hidden" name="step" value="2">
|
||||
<input type="hidden" name="step" value="1">
|
||||
|
||||
<?php if (count($langs) > 1): ?>
|
||||
<?php if (count($langs) > 1) : ?>
|
||||
<select style="float: right" onchange="location.href='?lang=' + this.value">
|
||||
<?php foreach ($langs as $key => $val): ?>
|
||||
<option value="<?php echo $key; ?>"<?php if ($lang == $key): ?> selected<?php endif; ?>><?php echo $val; ?></option>
|
||||
<?php foreach ($langs as $key => $val) : ?>
|
||||
<option value="<?php echo $key; ?>"<?php if ($lang == $key) :
|
||||
?> selected<?php
|
||||
endif; ?>><?php echo $val; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php endif; ?>
|
||||
@ -514,13 +733,62 @@ function install_step_1() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
<?php
|
||||
install_js_support();
|
||||
}
|
||||
|
||||
/**
|
||||
* check dependencies before install
|
||||
*/
|
||||
function install_step_1_perform()
|
||||
{
|
||||
$errors = [];
|
||||
$checks = [
|
||||
'mbstring',
|
||||
'json',
|
||||
'Reflection',
|
||||
['mysqli', 'sqlite3', 'pgsql', 'pdo_mysql', 'pdo_sqlite', 'pdo_pgsql']
|
||||
];
|
||||
|
||||
foreach ($checks as $check) {
|
||||
$error = install_check_extension(is_array($check) ? $check : [$check]);
|
||||
|
||||
if (!empty($error)) {
|
||||
$errors[] = $error;
|
||||
}
|
||||
}
|
||||
|
||||
$uploadDir = '/usr/uploads';
|
||||
$realUploadDir = \Typecho\Common::url($uploadDir, __TYPECHO_ROOT_DIR__);
|
||||
$writeable = true;
|
||||
if (is_dir($realUploadDir)) {
|
||||
if (!is_writeable($realUploadDir)) {
|
||||
if (!@chmod($realUploadDir, 0644)) {
|
||||
$writeable = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!@mkdir($realUploadDir, 0644)) {
|
||||
$writeable = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$writeable) {
|
||||
$errors[] = _t('上传目录无法写入, 请手动将安装目录下的 %s 目录的权限设置为可写然后继续升级', $uploadDir);
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
install_success(2);
|
||||
} else {
|
||||
install_raise_error(implode("\n", $errors));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* display step 2
|
||||
*/
|
||||
function install_step_2() {
|
||||
function install_step_2()
|
||||
{
|
||||
global $installDb;
|
||||
|
||||
$drivers = install_get_db_drivers();
|
||||
@ -528,11 +796,11 @@ function install_step_2() {
|
||||
$type = install_get_db_type($adapter);
|
||||
|
||||
if (!empty($installDb)) {
|
||||
$config = $installDb->getConfig(Typecho_Db::WRITE)->toArray();
|
||||
$config = $installDb->getConfig(\Typecho\Db::WRITE)->toArray();
|
||||
$config['prefix'] = $installDb->getPrefix();
|
||||
$config['adapter'] = $adapter;
|
||||
}
|
||||
?>
|
||||
?>
|
||||
<div class="row typecho-page-main">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
<div class="typecho-page-title">
|
||||
@ -543,8 +811,10 @@ function install_step_2() {
|
||||
<li>
|
||||
<label for="dbAdapter" class="typecho-label"><?php _e('数据库适配器'); ?></label>
|
||||
<select name="dbAdapter" id="dbAdapter" onchange="location.href='?step=2&driver=' + this.value">
|
||||
<?php foreach ($drivers as $driver => $name): ?>
|
||||
<option value="<?php echo $driver; ?>"<?php if($driver == $adapter): ?> selected="selected"<?php endif; ?>><?php echo $name; ?></option>
|
||||
<?php foreach ($drivers as $driver => $name) : ?>
|
||||
<option value="<?php echo $driver; ?>"<?php if ($driver == $adapter) :
|
||||
?> selected="selected"<?php
|
||||
endif; ?>><?php echo $name; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description"><?php _e('请根据您的数据库类型选择合适的适配器'); ?></p>
|
||||
@ -619,7 +889,7 @@ function install_step_2() {
|
||||
$('#dbNext').val('none');
|
||||
});
|
||||
|
||||
<?php if (!empty($config)): ?>
|
||||
<?php if (!empty($config)) : ?>
|
||||
function fillInput(config) {
|
||||
for (let k in config) {
|
||||
let value = config[k],
|
||||
@ -632,20 +902,21 @@ function install_step_2() {
|
||||
}
|
||||
}
|
||||
|
||||
fillInput(<?php echo Json::encode($config); ?>);
|
||||
fillInput(<?php echo json_encode($config); ?>);
|
||||
<?php endif; ?>
|
||||
</script>
|
||||
<?php
|
||||
<?php
|
||||
install_js_support();
|
||||
}
|
||||
|
||||
/**
|
||||
* perform install step 2
|
||||
*/
|
||||
function install_step_2_perform() {
|
||||
function install_step_2_perform()
|
||||
{
|
||||
global $installDb;
|
||||
|
||||
$request = Typecho_Request::getInstance();
|
||||
$request = \Typecho\Request::getInstance();
|
||||
$drivers = install_get_db_drivers();
|
||||
|
||||
$configMap = [
|
||||
@ -703,7 +974,7 @@ function install_step_2_perform() {
|
||||
]);
|
||||
}
|
||||
|
||||
$error = (new Typecho_Validate())
|
||||
$error = (new \Typecho\Validate())
|
||||
->addRule('dbPrefix', 'required', _t('确认您的配置'))
|
||||
->addRule('dbPrefix', 'minLength', _t('确认您的配置'), 1)
|
||||
->addRule('dbPrefix', 'maxLength', _t('确认您的配置'), 16)
|
||||
@ -722,12 +993,12 @@ function install_step_2_perform() {
|
||||
$dbConfig = [];
|
||||
|
||||
foreach ($configMap[$type] as $key => $value) {
|
||||
$config[$key] = $config[$key] === null ? (install_is_cli() ? $value : null) : $config[$key];
|
||||
$config[$key] = !isset($config[$key]) ? (install_is_cli() ? $value : null) : $config[$key];
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'Mysql':
|
||||
$error = (new Typecho_Validate())
|
||||
$error = (new \Typecho\Validate())
|
||||
->addRule('dbHost', 'required', _t('确认您的配置'))
|
||||
->addRule('dbPort', 'required', _t('确认您的配置'))
|
||||
->addRule('dbPort', 'isInteger', _t('确认您的配置'))
|
||||
@ -740,7 +1011,7 @@ function install_step_2_perform() {
|
||||
->run($config);
|
||||
break;
|
||||
case 'Pgsql':
|
||||
$error = (new Typecho_Validate())
|
||||
$error = (new \Typecho\Validate())
|
||||
->addRule('dbHost', 'required', _t('确认您的配置'))
|
||||
->addRule('dbPort', 'required', _t('确认您的配置'))
|
||||
->addRule('dbPort', 'isInteger', _t('确认您的配置'))
|
||||
@ -751,7 +1022,7 @@ function install_step_2_perform() {
|
||||
->run($config);
|
||||
break;
|
||||
case 'SQLite':
|
||||
$error = (new Typecho_Validate())
|
||||
$error = (new \Typecho\Validate())
|
||||
->addRule('dbFile', 'required', _t('确认您的配置'))
|
||||
->run($config);
|
||||
break;
|
||||
@ -775,12 +1046,12 @@ function install_step_2_perform() {
|
||||
} elseif (empty($installDb)) {
|
||||
// detect db config
|
||||
try {
|
||||
$installDb = new Typecho_Db($config['dbAdapter'], $config['dbPrefix']);
|
||||
$installDb->addServer($dbConfig, Typecho_Db::READ | Typecho_Db::WRITE);
|
||||
$installDb = new \Typecho\Db($config['dbAdapter'], $config['dbPrefix']);
|
||||
$installDb->addServer($dbConfig, \Typecho\Db::READ | \Typecho\Db::WRITE);
|
||||
$installDb->query('SELECT 1=1');
|
||||
} catch (Typecho_Db_Adapter_Exception $e) {
|
||||
} catch (\Typecho\Db\Adapter_Exception $e) {
|
||||
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装'));
|
||||
} catch (Typecho_Db_Exception $e) {
|
||||
} catch (\Typecho\Db\Exception $e) {
|
||||
install_raise_error(_t('安装程序捕捉到以下错误: " %s ". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
|
||||
}
|
||||
|
||||
@ -789,15 +1060,16 @@ function install_step_2_perform() {
|
||||
if (!install_check('config')) {
|
||||
install_raise_error(
|
||||
_t('安装程序无法自动创建 <strong>config.inc.php</strong> 文件') . "\n" .
|
||||
_t('您可以在网站根目录下手动创建 <strong>config.inc.php</strong> 文件, 并复制如下代码至其中')
|
||||
, [
|
||||
_t('您可以在网站根目录下手动创建 <strong>config.inc.php</strong> 文件, 并复制如下代码至其中'),
|
||||
[
|
||||
'code' => $code
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// delete exists db
|
||||
if($config['dbNext'] == 'delete') {
|
||||
if ($config['dbNext'] == 'delete') {
|
||||
$tables = [
|
||||
$config['dbPrefix'] . 'comments',
|
||||
$config['dbPrefix'] . 'contents',
|
||||
@ -818,7 +1090,7 @@ function install_step_2_perform() {
|
||||
$installDb->query("DROP TABLE {$table}");
|
||||
}
|
||||
}
|
||||
} catch (Typecho_Db_Exception $e) {
|
||||
} catch (\Typecho\Db\Exception $e) {
|
||||
install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
|
||||
}
|
||||
}
|
||||
@ -840,16 +1112,17 @@ function install_step_2_perform() {
|
||||
foreach ($scripts as $script) {
|
||||
$script = trim($script);
|
||||
if ($script) {
|
||||
$installDb->query($script, Typecho_Db::WRITE);
|
||||
$installDb->query($script, \Typecho\Db::WRITE);
|
||||
}
|
||||
}
|
||||
} catch (Typecho_Db_Exception $e) {
|
||||
} catch (\Typecho\Db\Exception $e) {
|
||||
$code = $e->getCode();
|
||||
|
||||
if(('Mysql' == $type && (1050 == $code || '42S01' == $code)) ||
|
||||
if (
|
||||
('Mysql' == $type && (1050 == $code || '42S01' == $code)) ||
|
||||
('SQLite' == $type && ('HY000' == $code || 1 == $code)) ||
|
||||
('Pgsql' == $type && '42P07' == $code)) {
|
||||
|
||||
('Pgsql' == $type && '42P07' == $code)
|
||||
) {
|
||||
if ($config['dbNext'] == 'keep') {
|
||||
if (install_check('db_data')) {
|
||||
install_success(0);
|
||||
@ -877,9 +1150,10 @@ function install_step_2_perform() {
|
||||
/**
|
||||
* display step 3
|
||||
*/
|
||||
function install_step_3() {
|
||||
$options = Typecho_Widget::widget('Widget_Options');
|
||||
?>
|
||||
function install_step_3()
|
||||
{
|
||||
$options = \Widget\Options::alloc();
|
||||
?>
|
||||
<div class="row typecho-page-main">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
<div class="typecho-page-title">
|
||||
@ -923,19 +1197,20 @@ function install_step_3() {
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
<?php
|
||||
install_js_support();
|
||||
}
|
||||
|
||||
/**
|
||||
* perform step 3
|
||||
*/
|
||||
function install_step_3_perform() {
|
||||
function install_step_3_perform()
|
||||
{
|
||||
global $installDb;
|
||||
|
||||
$request = Typecho_Request::getInstance();
|
||||
$defaultPassword = Typecho_Common::randString(8);
|
||||
$options = Typecho_Widget::widget('Widget_Options');
|
||||
$request = \Typecho\Request::getInstance();
|
||||
$defaultPassword = \Typecho\Common::randString(8);
|
||||
$options = \Widget\Options::alloc();
|
||||
|
||||
if (install_is_cli()) {
|
||||
$config = [
|
||||
@ -953,10 +1228,10 @@ function install_step_3_perform() {
|
||||
]);
|
||||
}
|
||||
|
||||
$error = (new Typecho_Validate())
|
||||
$error = (new \Typecho\Validate())
|
||||
->addRule('userUrl', 'required', _t('请填写站点地址'))
|
||||
->addRule('userUrl', 'url', _t('请填写一个合法的URL地址'))
|
||||
->addRule('userName', 'required', _t('必须填写用户名称'))
|
||||
->addRule('userName', 'required', _t('必须填写用户名称'))
|
||||
->addRule('userName', 'xssCheck', _t('请不要在用户名中使用特殊字符'))
|
||||
->addRule('userName', 'maxLength', _t('用户名长度超过限制, 请不要超过 32 个字符'), 32)
|
||||
->addRule('userMail', 'required', _t('必须填写电子邮箱'))
|
||||
@ -981,16 +1256,16 @@ function install_step_3_perform() {
|
||||
}
|
||||
|
||||
// write user
|
||||
$hasher = new PasswordHash(8, true);
|
||||
$hasher = new \Utils\PasswordHash(8, true);
|
||||
$installDb->query(
|
||||
$installDb->insert('table.users')->rows([
|
||||
'name' => $config['userName'],
|
||||
'password' => $hasher->HashPassword($config['userPassword']),
|
||||
'password' => $hasher->hashPassword($config['userPassword']),
|
||||
'mail' => $config['userMail'],
|
||||
'url' => $options->siteUrl,
|
||||
'screenName' => $config['userName'],
|
||||
'group' => 'administrator',
|
||||
'created' => Typecho_Date::time()
|
||||
'created' => \Typecho\Date::time()
|
||||
])
|
||||
);
|
||||
|
||||
@ -1012,8 +1287,8 @@ function install_step_3_perform() {
|
||||
$installDb->query(
|
||||
$installDb->insert('table.contents')->rows([
|
||||
'title' => _t('欢迎使用 Typecho'),
|
||||
'slug' => 'start', 'created' => Typecho_Date::time(),
|
||||
'modified' => Typecho_Date::time(),
|
||||
'slug' => 'start', 'created' => \Typecho\Date::time(),
|
||||
'modified' => \Typecho\Date::time(),
|
||||
'text' => '<!--markdown-->' . _t('如果您看到这篇文章,表示您的 blog 已经安装成功.'),
|
||||
'authorId' => 1,
|
||||
'type' => 'post',
|
||||
@ -1030,8 +1305,8 @@ function install_step_3_perform() {
|
||||
$installDb->insert('table.contents')->rows([
|
||||
'title' => _t('关于'),
|
||||
'slug' => 'start-page',
|
||||
'created' => Typecho_Date::time(),
|
||||
'modified' => Typecho_Date::time(),
|
||||
'created' => \Typecho\Date::time(),
|
||||
'modified' => \Typecho\Date::time(),
|
||||
'text' => '<!--markdown-->' . _t('本页面由 Typecho 创建, 这只是个测试页面.'),
|
||||
'authorId' => 1,
|
||||
'order' => 0,
|
||||
@ -1048,7 +1323,7 @@ function install_step_3_perform() {
|
||||
// write comment
|
||||
$installDb->query(
|
||||
$installDb->insert('table.comments')->rows([
|
||||
'cid' => 1, 'created' => Typecho_Date::time(),
|
||||
'cid' => 1, 'created' => \Typecho\Date::time(),
|
||||
'author' => 'Typecho',
|
||||
'ownerId' => 1,
|
||||
'url' => 'http://typecho.org',
|
||||
@ -1060,7 +1335,7 @@ function install_step_3_perform() {
|
||||
'parent' => 0
|
||||
])
|
||||
);
|
||||
} catch (Typecho_Db_Exception $e) {
|
||||
} catch (\Typecho\Db\Exception $e) {
|
||||
install_raise_error($e->getMessage());
|
||||
}
|
||||
|
||||
@ -1070,12 +1345,12 @@ function install_step_3_perform() {
|
||||
'password' => $config['userPassword'],
|
||||
'referer' => $options->adminUrl
|
||||
]);
|
||||
$loginUrl = Typecho_Common::buildUrl($parts);
|
||||
$loginUrl = \Typecho\Common::buildUrl($parts);
|
||||
|
||||
install_success(0, [
|
||||
$config['userName'],
|
||||
$config['userPassword'],
|
||||
Typecho_Widget::widget('Widget_Security')->getTokenUrl($loginUrl, $request->getReferer()),
|
||||
\Widget\Security::alloc()->getTokenUrl($loginUrl, $request->getReferer()),
|
||||
$options->siteUrl
|
||||
]);
|
||||
}
|
||||
@ -1083,9 +1358,9 @@ function install_step_3_perform() {
|
||||
/**
|
||||
* dispatch install action
|
||||
*
|
||||
* @throws Typecho_Exception
|
||||
*/
|
||||
function install_dispatch() {
|
||||
function install_dispatch()
|
||||
{
|
||||
define('__TYPECHO_INSTALL__', true);
|
||||
|
||||
// disable root url on cli mode
|
||||
@ -1094,8 +1369,8 @@ function install_dispatch() {
|
||||
}
|
||||
|
||||
// init default options
|
||||
$options = Typecho_Widget::widget('Widget_Options', install_get_default_options());
|
||||
Typecho_Widget::widget('Widget_Init');
|
||||
$options = \Widget\Options::alloc(install_get_default_options());
|
||||
\Widget\Init::alloc();
|
||||
|
||||
// install finished yet
|
||||
if (
|
||||
@ -1105,17 +1380,16 @@ function install_dispatch() {
|
||||
) {
|
||||
// redirect to siteUrl if not cli
|
||||
if (!install_is_cli()) {
|
||||
Typecho_Response::getInstance()->redirect($options->siteUrl);
|
||||
install_redirect($options->siteUrl);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (install_is_cli()) {
|
||||
install_step_2_perform();
|
||||
install_step_1_perform();
|
||||
} else {
|
||||
$request = Typecho_Request::getInstance();
|
||||
$response = Typecho_Response::getInstance();
|
||||
$request = \Typecho\Request::getInstance();
|
||||
$step = $request->get('step');
|
||||
|
||||
$action = 1;
|
||||
@ -1125,14 +1399,14 @@ function install_dispatch() {
|
||||
if (!install_check('db_structure')) {
|
||||
$action = 2;
|
||||
} else {
|
||||
$response->redirect('install.php?step=3');
|
||||
install_redirect('install.php?step=3');
|
||||
}
|
||||
break;
|
||||
case $step == 3:
|
||||
if (install_check('db_structure')) {
|
||||
$action = 3;
|
||||
} else {
|
||||
$response->redirect('install.php?step=2');
|
||||
install_redirect('install.php?step=2');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1141,12 +1415,12 @@ function install_dispatch() {
|
||||
|
||||
$method = 'install_step_' . $action;
|
||||
|
||||
if ($request->isPost() && $action > 1) {
|
||||
if ($request->isPost()) {
|
||||
$method .= '_perform';
|
||||
$method();
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
?>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
@ -1166,7 +1440,7 @@ function install_dispatch() {
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,11 @@ $langs = [];
|
||||
|
||||
/**
|
||||
* output lang
|
||||
*
|
||||
*
|
||||
* @param string $str
|
||||
*/
|
||||
function output_lang($str) {
|
||||
function output_lang(string $str)
|
||||
{
|
||||
global $langs;
|
||||
|
||||
$key = md5($str);
|
||||
@ -19,19 +20,20 @@ function output_lang($str) {
|
||||
|
||||
/**
|
||||
* get all files
|
||||
*
|
||||
*
|
||||
* @param string $dir
|
||||
* @param string $pattern
|
||||
* @return array
|
||||
*/
|
||||
function all_files($dir, $pattern = '*') {
|
||||
$result = array();
|
||||
function all_files(string $dir, string $pattern = '*'): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
$items = glob($dir . '/' . $pattern, GLOB_BRACE);
|
||||
foreach ($items as $item) {
|
||||
if (is_file($item)) {
|
||||
$result[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$items = glob($dir . '/*', GLOB_ONLYDIR);
|
||||
@ -46,11 +48,12 @@ function all_files($dir, $pattern = '*') {
|
||||
|
||||
/**
|
||||
* get msgid
|
||||
*
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
function get_msgid($value) {
|
||||
function get_msgid(string $value): string
|
||||
{
|
||||
if ($value[0] == '"') {
|
||||
return $value;
|
||||
} else {
|
||||
@ -61,22 +64,22 @@ function get_msgid($value) {
|
||||
|
||||
/**
|
||||
* get pot from file
|
||||
*
|
||||
*
|
||||
* @param string $file
|
||||
* @return string
|
||||
*/
|
||||
function get_pot($file) {
|
||||
function get_pot(string $file)
|
||||
{
|
||||
$source = file_get_contents($file);
|
||||
$matched = null;
|
||||
$plural = [];
|
||||
|
||||
foreach (token_get_all($source) as $token) {
|
||||
if (is_array($token)) {
|
||||
list ($type, $value) = $token;
|
||||
[$type, $value] = $token;
|
||||
|
||||
if ($type == T_STRING && in_array($value, ['_t', '_e', '_n'])) {
|
||||
$matched = $value;
|
||||
} else if ($type == T_CONSTANT_ENCAPSED_STRING && $matched) {
|
||||
} elseif ($type == T_CONSTANT_ENCAPSED_STRING && $matched) {
|
||||
$key = md5($value);
|
||||
|
||||
if ($matched == '_n') {
|
||||
@ -85,7 +88,7 @@ function get_pot($file) {
|
||||
output_lang('msgid ' . get_msgid($value) . "\nmsgstr \"\"\n\n");
|
||||
$matched = null;
|
||||
}
|
||||
} else if ($type != T_WHITESPACE) {
|
||||
} elseif ($type != T_WHITESPACE) {
|
||||
$matched = null;
|
||||
|
||||
if (!empty($plural)) {
|
||||
@ -102,16 +105,13 @@ function get_pot($file) {
|
||||
$plural = [];
|
||||
}
|
||||
}
|
||||
} else if ($token != ',' && $token != '(') {
|
||||
} elseif ($token != ',' && $token != '(') {
|
||||
$matched = null;
|
||||
$plural = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../var/Typecho/Common.php';
|
||||
|
||||
|
||||
echo <<<EOF
|
||||
# Copyright (C) Typecho
|
||||
# This file is distributed under the same license as the Typecho Project.
|
||||
|
@ -1,70 +1,72 @@
|
||||
<?php
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
|
||||
namespace HelloWorld;
|
||||
|
||||
use Typecho\Plugin\PluginInterface;
|
||||
use Typecho\Widget\Helper\Form;
|
||||
use Typecho\Widget\Helper\Form\Element\Text;
|
||||
use Widget\Options;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hello World
|
||||
*
|
||||
* @package HelloWorld
|
||||
*
|
||||
* @package HelloWorld
|
||||
* @author qining
|
||||
* @version 1.0.0
|
||||
* @link http://typecho.org
|
||||
*/
|
||||
class HelloWorld_Plugin implements Typecho_Plugin_Interface
|
||||
class Plugin implements PluginInterface
|
||||
{
|
||||
/**
|
||||
* 激活插件方法,如果激活失败,直接抛出异常
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws Typecho_Plugin_Exception
|
||||
*/
|
||||
public static function activate()
|
||||
{
|
||||
Typecho_Plugin::factory('admin/menu.php')->navBar = array('HelloWorld_Plugin', 'render');
|
||||
\Typecho\Plugin::factory('admin/menu.php')->navBar = ['HelloWorld_Plugin', 'render'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 禁用插件方法,如果禁用失败,直接抛出异常
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws Typecho_Plugin_Exception
|
||||
*/
|
||||
public static function deactivate(){}
|
||||
|
||||
public static function deactivate()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件配置面板
|
||||
*
|
||||
* @access public
|
||||
* @param Typecho_Widget_Helper_Form $form 配置面板
|
||||
* @return void
|
||||
*
|
||||
* @param Form $form 配置面板
|
||||
*/
|
||||
public static function config(Typecho_Widget_Helper_Form $form)
|
||||
public static function config(Form $form)
|
||||
{
|
||||
/** 分类名称 */
|
||||
$name = new Typecho_Widget_Helper_Form_Element_Text('word', NULL, 'Hello World', _t('说点什么'));
|
||||
$name = new Text('word', null, 'Hello World', _t('说点什么'));
|
||||
$form->addInput($name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 个人用户的配置面板
|
||||
*
|
||||
* @access public
|
||||
* @param Typecho_Widget_Helper_Form $form
|
||||
* @return void
|
||||
*
|
||||
* @param Form $form
|
||||
*/
|
||||
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
|
||||
|
||||
public static function personalConfig(Form $form)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件实现方法
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function render()
|
||||
{
|
||||
echo '<span class="message success">'
|
||||
. htmlspecialchars(Typecho_Widget::widget('Widget_Options')->plugin('HelloWorld')->word)
|
||||
. htmlspecialchars(Options::alloc()->plugin('HelloWorld')->word)
|
||||
. '</span>';
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,18 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
||||
|
||||
<div class="error-page">
|
||||
<h2 class="post-title">404 - <?php _e('页面没找到'); ?></h2>
|
||||
<p><?php _e('你想查看的页面已被转移或删除了, 要不要搜索看看: '); ?></p>
|
||||
<form method="post">
|
||||
<p><input type="text" name="s" class="text" autofocus /></p>
|
||||
<p><button type="submit" class="submit"><?php _e('搜索'); ?></button></p>
|
||||
</form>
|
||||
</div>
|
||||
<div class="error-page">
|
||||
<h2 class="post-title">404 - <?php _e('页面没找到'); ?></h2>
|
||||
<p><?php _e('你想查看的页面已被转移或删除了, 要不要搜索看看: '); ?></p>
|
||||
<form method="post">
|
||||
<p><input type="text" name="s" class="text" autofocus/></p>
|
||||
<p>
|
||||
<button type="submit" class="submit"><?php _e('搜索'); ?></button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div><!-- end #content-->
|
||||
<?php $this->need('footer.php'); ?>
|
||||
</div><!-- end #content-->
|
||||
<?php $this->need('footer.php'); ?>
|
||||
|
@ -1,36 +1,45 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
|
||||
<div class="col-mb-12 col-8" id="main" role="main">
|
||||
<h3 class="archive-title"><?php $this->archiveTitle(array(
|
||||
'category' => _t('分类 %s 下的文章'),
|
||||
'search' => _t('包含关键字 %s 的文章'),
|
||||
'tag' => _t('标签 %s 下的文章'),
|
||||
'author' => _t('%s 发布的文章')
|
||||
), '', ''); ?></h3>
|
||||
<?php if ($this->have()): ?>
|
||||
<?php while($this->next()): ?>
|
||||
<div class="col-mb-12 col-8" id="main" role="main">
|
||||
<h3 class="archive-title"><?php $this->archiveTitle([
|
||||
'category' => _t('分类 %s 下的文章'),
|
||||
'search' => _t('包含关键字 %s 的文章'),
|
||||
'tag' => _t('标签 %s 下的文章'),
|
||||
'author' => _t('%s 发布的文章')
|
||||
], '', ''); ?></h3>
|
||||
<?php if ($this->have()): ?>
|
||||
<?php while ($this->next()): ?>
|
||||
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
<h2 class="post-title" itemprop="name headline"><a itemprop="url" href="<?php $this->permalink() ?>"><?php $this->title() ?></a></h2>
|
||||
<ul class="post-meta">
|
||||
<li itemprop="author" itemscope itemtype="http://schema.org/Person"><?php _e('作者: '); ?><a itemprop="name" href="<?php $this->author->permalink(); ?>" rel="author"><?php $this->author(); ?></a></li>
|
||||
<li><?php _e('时间: '); ?><time datetime="<?php $this->date('c'); ?>" itemprop="datePublished"><?php $this->date(); ?></time></li>
|
||||
<li><?php _e('分类: '); ?><?php $this->category(','); ?></li>
|
||||
<li itemprop="interactionCount"><a href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('评论', '1 条评论', '%d 条评论'); ?></a></li>
|
||||
</ul>
|
||||
<h2 class="post-title" itemprop="name headline"><a itemprop="url"
|
||||
href="<?php $this->permalink() ?>"><?php $this->title() ?></a>
|
||||
</h2>
|
||||
<ul class="post-meta">
|
||||
<li itemprop="author" itemscope itemtype="http://schema.org/Person"><?php _e('作者: '); ?><a
|
||||
itemprop="name" href="<?php $this->author->permalink(); ?>"
|
||||
rel="author"><?php $this->author(); ?></a></li>
|
||||
<li><?php _e('时间: '); ?>
|
||||
<time datetime="<?php $this->date('c'); ?>"
|
||||
itemprop="datePublished"><?php $this->date(); ?></time>
|
||||
</li>
|
||||
<li><?php _e('分类: '); ?><?php $this->category(','); ?></li>
|
||||
<li itemprop="interactionCount"><a
|
||||
href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('评论', '1 条评论', '%d 条评论'); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="post-content" itemprop="articleBody">
|
||||
<?php $this->content('- 阅读剩余部分 -'); ?>
|
||||
<?php $this->content('- 阅读剩余部分 -'); ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<article class="post">
|
||||
<h2 class="post-title"><?php _e('没有找到内容'); ?></h2>
|
||||
</article>
|
||||
<?php endif; ?>
|
||||
<?php endwhile; ?>
|
||||
<?php else: ?>
|
||||
<article class="post">
|
||||
<h2 class="post-title"><?php _e('没有找到内容'); ?></h2>
|
||||
</article>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php $this->pageNav('« 前一页', '后一页 »'); ?>
|
||||
</div><!-- end #main -->
|
||||
<?php $this->pageNav('« 前一页', '后一页 »'); ?>
|
||||
</div><!-- end #main -->
|
||||
|
||||
<?php $this->need('sidebar.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
<?php $this->need('sidebar.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
|
@ -2,48 +2,57 @@
|
||||
<div id="comments">
|
||||
<?php $this->comments()->to($comments); ?>
|
||||
<?php if ($comments->have()): ?>
|
||||
<h3><?php $this->commentsNum(_t('暂无评论'), _t('仅有一条评论'), _t('已有 %d 条评论')); ?></h3>
|
||||
|
||||
<?php $comments->listComments(); ?>
|
||||
<h3><?php $this->commentsNum(_t('暂无评论'), _t('仅有一条评论'), _t('已有 %d 条评论')); ?></h3>
|
||||
|
||||
<?php $comments->listComments(); ?>
|
||||
|
||||
<?php $comments->pageNav('« 前一页', '后一页 »'); ?>
|
||||
|
||||
<?php $comments->pageNav('« 前一页', '后一页 »'); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($this->allow('comment')): ?>
|
||||
<div id="<?php $this->respondId(); ?>" class="respond">
|
||||
<div class="cancel-comment-reply">
|
||||
<?php $comments->cancelReply(); ?>
|
||||
<?php if ($this->allow('comment')): ?>
|
||||
<div id="<?php $this->respondId(); ?>" class="respond">
|
||||
<div class="cancel-comment-reply">
|
||||
<?php $comments->cancelReply(); ?>
|
||||
</div>
|
||||
|
||||
<h3 id="response"><?php _e('添加新评论'); ?></h3>
|
||||
<form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" role="form">
|
||||
<?php if ($this->user->hasLogin()): ?>
|
||||
<p><?php _e('登录身份: '); ?><a
|
||||
href="<?php $this->options->profileUrl(); ?>"><?php $this->user->screenName(); ?></a>. <a
|
||||
href="<?php $this->options->logoutUrl(); ?>" title="Logout"><?php _e('退出'); ?> »</a>
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<p>
|
||||
<label for="author" class="required"><?php _e('称呼'); ?></label>
|
||||
<input type="text" name="author" id="author" class="text"
|
||||
value="<?php $this->remember('author'); ?>" required/>
|
||||
</p>
|
||||
<p>
|
||||
<label
|
||||
for="mail"<?php if ($this->options->commentsRequireMail): ?> class="required"<?php endif; ?>><?php _e('Email'); ?></label>
|
||||
<input type="email" name="mail" id="mail" class="text"
|
||||
value="<?php $this->remember('mail'); ?>"<?php if ($this->options->commentsRequireMail): ?> required<?php endif; ?> />
|
||||
</p>
|
||||
<p>
|
||||
<label
|
||||
for="url"<?php if ($this->options->commentsRequireURL): ?> class="required"<?php endif; ?>><?php _e('网站'); ?></label>
|
||||
<input type="url" name="url" id="url" class="text" placeholder="<?php _e('http://'); ?>"
|
||||
value="<?php $this->remember('url'); ?>"<?php if ($this->options->commentsRequireURL): ?> required<?php endif; ?> />
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<p>
|
||||
<label for="textarea" class="required"><?php _e('内容'); ?></label>
|
||||
<textarea rows="8" cols="50" name="text" id="textarea" class="textarea"
|
||||
required><?php $this->remember('text'); ?></textarea>
|
||||
</p>
|
||||
<p>
|
||||
<button type="submit" class="submit"><?php _e('提交评论'); ?></button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<h3 id="response"><?php _e('添加新评论'); ?></h3>
|
||||
<form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" role="form">
|
||||
<?php if($this->user->hasLogin()): ?>
|
||||
<p><?php _e('登录身份: '); ?><a href="<?php $this->options->profileUrl(); ?>"><?php $this->user->screenName(); ?></a>. <a href="<?php $this->options->logoutUrl(); ?>" title="Logout"><?php _e('退出'); ?> »</a></p>
|
||||
<?php else: ?>
|
||||
<p>
|
||||
<label for="author" class="required"><?php _e('称呼'); ?></label>
|
||||
<input type="text" name="author" id="author" class="text" value="<?php $this->remember('author'); ?>" required />
|
||||
</p>
|
||||
<p>
|
||||
<label for="mail"<?php if ($this->options->commentsRequireMail): ?> class="required"<?php endif; ?>><?php _e('Email'); ?></label>
|
||||
<input type="email" name="mail" id="mail" class="text" value="<?php $this->remember('mail'); ?>"<?php if ($this->options->commentsRequireMail): ?> required<?php endif; ?> />
|
||||
</p>
|
||||
<p>
|
||||
<label for="url"<?php if ($this->options->commentsRequireURL): ?> class="required"<?php endif; ?>><?php _e('网站'); ?></label>
|
||||
<input type="url" name="url" id="url" class="text" placeholder="<?php _e('http://'); ?>" value="<?php $this->remember('url'); ?>"<?php if ($this->options->commentsRequireURL): ?> required<?php endif; ?> />
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<p>
|
||||
<label for="textarea" class="required"><?php _e('内容'); ?></label>
|
||||
<textarea rows="8" cols="50" name="text" id="textarea" class="textarea" required ><?php $this->remember('text'); ?></textarea>
|
||||
</p>
|
||||
<p>
|
||||
<button type="submit" class="submit"><?php _e('提交评论'); ?></button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<h3><?php _e('评论已关闭'); ?></h3>
|
||||
<h3><?php _e('评论已关闭'); ?></h3>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
@ -1,26 +1,44 @@
|
||||
<?php
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
|
||||
function themeConfig($form) {
|
||||
$logoUrl = new Typecho_Widget_Helper_Form_Element_Text('logoUrl', NULL, NULL, _t('站点 LOGO 地址'), _t('在这里填入一个图片 URL 地址, 以在网站标题前加上一个 LOGO'));
|
||||
function themeConfig($form)
|
||||
{
|
||||
$logoUrl = new \Typecho\Widget\Helper\Form\Element\Text(
|
||||
'logoUrl',
|
||||
null,
|
||||
null,
|
||||
_t('站点 LOGO 地址'),
|
||||
_t('在这里填入一个图片 URL 地址, 以在网站标题前加上一个 LOGO')
|
||||
);
|
||||
|
||||
$form->addInput($logoUrl);
|
||||
|
||||
$sidebarBlock = new Typecho_Widget_Helper_Form_Element_Checkbox('sidebarBlock',
|
||||
array('ShowRecentPosts' => _t('显示最新文章'),
|
||||
'ShowRecentComments' => _t('显示最近回复'),
|
||||
'ShowCategory' => _t('显示分类'),
|
||||
'ShowArchive' => _t('显示归档'),
|
||||
'ShowOther' => _t('显示其它杂项')),
|
||||
array('ShowRecentPosts', 'ShowRecentComments', 'ShowCategory', 'ShowArchive', 'ShowOther'), _t('侧边栏显示'));
|
||||
|
||||
|
||||
$sidebarBlock = new \Typecho\Widget\Helper\Form\Element\Checkbox(
|
||||
'sidebarBlock',
|
||||
[
|
||||
'ShowRecentPosts' => _t('显示最新文章'),
|
||||
'ShowRecentComments' => _t('显示最近回复'),
|
||||
'ShowCategory' => _t('显示分类'),
|
||||
'ShowArchive' => _t('显示归档'),
|
||||
'ShowOther' => _t('显示其它杂项')
|
||||
],
|
||||
['ShowRecentPosts', 'ShowRecentComments', 'ShowCategory', 'ShowArchive', 'ShowOther'],
|
||||
_t('侧边栏显示')
|
||||
);
|
||||
|
||||
$form->addInput($sidebarBlock->multiMode());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
function themeFields($layout) {
|
||||
$logoUrl = new Typecho_Widget_Helper_Form_Element_Text('logoUrl', NULL, NULL, _t('站点LOGO地址'), _t('在这里填入一个图片URL地址, 以在网站标题前加上一个LOGO'));
|
||||
function themeFields($layout)
|
||||
{
|
||||
$logoUrl = new \Typecho\Widget\Helper\Form\Element\Text(
|
||||
'logoUrl',
|
||||
null,
|
||||
null,
|
||||
_t('站点LOGO地址'),
|
||||
_t('在这里填入一个图片URL地址, 以在网站标题前加上一个LOGO')
|
||||
);
|
||||
$layout->addItem($logoUrl);
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -3,60 +3,54 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="<?php $this->options->charset(); ?>">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title><?php $this->archiveTitle(array(
|
||||
'category' => _t('分类 %s 下的文章'),
|
||||
'search' => _t('包含关键字 %s 的文章'),
|
||||
'tag' => _t('标签 %s 下的文章'),
|
||||
'author' => _t('%s 发布的文章')
|
||||
), '', ' - '); ?><?php $this->options->title(); ?></title>
|
||||
<title><?php $this->archiveTitle([
|
||||
'category' => _t('分类 %s 下的文章'),
|
||||
'search' => _t('包含关键字 %s 的文章'),
|
||||
'tag' => _t('标签 %s 下的文章'),
|
||||
'author' => _t('%s 发布的文章')
|
||||
], '', ' - '); ?><?php $this->options->title(); ?></title>
|
||||
|
||||
<!-- 使用url函数转换相关路径 -->
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('normalize.css'); ?>">
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('grid.css'); ?>">
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('style.css'); ?>">
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<!-- 通过自有函数输出HTML头部信息 -->
|
||||
<?php $this->header(); ?>
|
||||
</head>
|
||||
<body>
|
||||
<!--[if lt IE 8]>
|
||||
<div class="browsehappy" role="dialog"><?php _e('当前网页 <strong>不支持</strong> 你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>'); ?>.</div>
|
||||
<![endif]-->
|
||||
|
||||
<header id="header" class="clearfix">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="site-name col-mb-12 col-9">
|
||||
<?php if ($this->options->logoUrl): ?>
|
||||
<a id="logo" href="<?php $this->options->siteUrl(); ?>">
|
||||
<img src="<?php $this->options->logoUrl() ?>" alt="<?php $this->options->title() ?>" />
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<a id="logo" href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title() ?></a>
|
||||
<p class="description"><?php $this->options->description() ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if ($this->options->logoUrl): ?>
|
||||
<a id="logo" href="<?php $this->options->siteUrl(); ?>">
|
||||
<img src="<?php $this->options->logoUrl() ?>" alt="<?php $this->options->title() ?>"/>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<a id="logo" href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title() ?></a>
|
||||
<p class="description"><?php $this->options->description() ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="site-search col-3 kit-hidden-tb">
|
||||
<form id="search" method="post" action="<?php $this->options->siteUrl(); ?>" role="search">
|
||||
<label for="s" class="sr-only"><?php _e('搜索关键字'); ?></label>
|
||||
<input type="text" id="s" name="s" class="text" placeholder="<?php _e('输入关键字搜索'); ?>" />
|
||||
<input type="text" id="s" name="s" class="text" placeholder="<?php _e('输入关键字搜索'); ?>"/>
|
||||
<button type="submit" class="submit"><?php _e('搜索'); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-mb-12">
|
||||
<nav id="nav-menu" class="clearfix" role="navigation">
|
||||
<a<?php if($this->is('index')): ?> class="current"<?php endif; ?> href="<?php $this->options->siteUrl(); ?>"><?php _e('首页'); ?></a>
|
||||
<?php $this->widget('Widget_Contents_Page_List')->to($pages); ?>
|
||||
<?php while($pages->next()): ?>
|
||||
<a<?php if($this->is('page', $pages->slug)): ?> class="current"<?php endif; ?> href="<?php $pages->permalink(); ?>" title="<?php $pages->title(); ?>"><?php $pages->title(); ?></a>
|
||||
<a<?php if ($this->is('index')): ?> class="current"<?php endif; ?>
|
||||
href="<?php $this->options->siteUrl(); ?>"><?php _e('首页'); ?></a>
|
||||
<?php \Widget\Contents\Page\Rows::alloc()->to($pages); ?>
|
||||
<?php while ($pages->next()): ?>
|
||||
<a<?php if ($this->is('page', $pages->slug)): ?> class="current"<?php endif; ?>
|
||||
href="<?php $pages->permalink(); ?>"
|
||||
title="<?php $pages->title(); ?>"><?php $pages->title(); ?></a>
|
||||
<?php endwhile; ?>
|
||||
</nav>
|
||||
</div>
|
||||
|
@ -1,32 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Default theme for Typecho
|
||||
*
|
||||
* @package Typecho Replica Theme
|
||||
*
|
||||
* @package Typecho Replica Theme
|
||||
* @author Typecho Team
|
||||
* @version 1.2
|
||||
* @link http://typecho.org
|
||||
*/
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
$this->need('header.php');
|
||||
?>
|
||||
$this->need('header.php');
|
||||
?>
|
||||
|
||||
<div class="col-mb-12 col-8" id="main" role="main">
|
||||
<?php while($this->next()): ?>
|
||||
<?php while ($this->next()): ?>
|
||||
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
<h2 class="post-title" itemprop="name headline"><a itemprop="url" href="<?php $this->permalink() ?>"><?php $this->title() ?></a></h2>
|
||||
<ul class="post-meta">
|
||||
<li itemprop="author" itemscope itemtype="http://schema.org/Person"><?php _e('作者: '); ?><a itemprop="name" href="<?php $this->author->permalink(); ?>" rel="author"><?php $this->author(); ?></a></li>
|
||||
<li><?php _e('时间: '); ?><time datetime="<?php $this->date('c'); ?>" itemprop="datePublished"><?php $this->date(); ?></time></li>
|
||||
<li><?php _e('分类: '); ?><?php $this->category(','); ?></li>
|
||||
<li itemprop="interactionCount"><a itemprop="discussionUrl" href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('评论', '1 条评论', '%d 条评论'); ?></a></li>
|
||||
</ul>
|
||||
<h2 class="post-title" itemprop="name headline">
|
||||
<a itemprop="url"
|
||||
href="<?php $this->permalink() ?>"><?php $this->title() ?></a>
|
||||
</h2>
|
||||
<ul class="post-meta">
|
||||
<li itemprop="author" itemscope itemtype="http://schema.org/Person"><?php _e('作者: '); ?><a
|
||||
itemprop="name" href="<?php $this->author->permalink(); ?>"
|
||||
rel="author"><?php $this->author(); ?></a></li>
|
||||
<li><?php _e('时间: '); ?>
|
||||
<time datetime="<?php $this->date('c'); ?>" itemprop="datePublished"><?php $this->date(); ?></time>
|
||||
</li>
|
||||
<li><?php _e('分类: '); ?><?php $this->category(','); ?></li>
|
||||
<li itemprop="interactionCount">
|
||||
<a itemprop="discussionUrl"
|
||||
href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('评论', '1 条评论', '%d 条评论'); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="post-content" itemprop="articleBody">
|
||||
<?php $this->content('- 阅读剩余部分 -'); ?>
|
||||
<?php $this->content('- 阅读剩余部分 -'); ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endwhile; ?>
|
||||
<?php endwhile; ?>
|
||||
|
||||
<?php $this->pageNav('« 前一页', '后一页 »'); ?>
|
||||
</div><!-- end #main-->
|
||||
|
@ -3,7 +3,10 @@
|
||||
|
||||
<div class="col-mb-12 col-8" id="main" role="main">
|
||||
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
<h1 class="post-title" itemprop="name headline"><a itemprop="url" href="<?php $this->permalink() ?>"><?php $this->title() ?></a></h1>
|
||||
<h1 class="post-title" itemprop="name headline">
|
||||
<a itemprop="url"
|
||||
href="<?php $this->permalink() ?>"><?php $this->title() ?></a>
|
||||
</h1>
|
||||
<div class="post-content" itemprop="articleBody">
|
||||
<?php $this->content(); ?>
|
||||
</div>
|
||||
|
@ -3,10 +3,19 @@
|
||||
|
||||
<div class="col-mb-12 col-8" id="main" role="main">
|
||||
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
<h1 class="post-title" itemprop="name headline"><a itemprop="url" href="<?php $this->permalink() ?>"><?php $this->title() ?></a></h1>
|
||||
<h1 class="post-title" itemprop="name headline">
|
||||
<a itemprop="url"
|
||||
href="<?php $this->permalink() ?>"><?php $this->title() ?></a>
|
||||
</h1>
|
||||
<ul class="post-meta">
|
||||
<li itemprop="author" itemscope itemtype="http://schema.org/Person"><?php _e('作者: '); ?><a itemprop="name" href="<?php $this->author->permalink(); ?>" rel="author"><?php $this->author(); ?></a></li>
|
||||
<li><?php _e('时间: '); ?><time datetime="<?php $this->date('c'); ?>" itemprop="datePublished"><?php $this->date(); ?></time></li>
|
||||
<li itemprop="author" itemscope itemtype="http://schema.org/Person">
|
||||
<?php _e('作者: '); ?><a itemprop="name"
|
||||
href="<?php $this->author->permalink(); ?>"
|
||||
rel="author"><?php $this->author(); ?></a>
|
||||
</li>
|
||||
<li><?php _e('时间: '); ?>
|
||||
<time datetime="<?php $this->date('c'); ?>" itemprop="datePublished"><?php $this->date(); ?></time>
|
||||
</li>
|
||||
<li><?php _e('分类: '); ?><?php $this->category(','); ?></li>
|
||||
</ul>
|
||||
<div class="post-content" itemprop="articleBody">
|
||||
@ -18,8 +27,8 @@
|
||||
<?php $this->need('comments.php'); ?>
|
||||
|
||||
<ul class="post-near">
|
||||
<li>上一篇: <?php $this->thePrev('%s','没有了'); ?></li>
|
||||
<li>下一篇: <?php $this->theNext('%s','没有了'); ?></li>
|
||||
<li>上一篇: <?php $this->thePrev('%s', '没有了'); ?></li>
|
||||
<li>下一篇: <?php $this->theNext('%s', '没有了'); ?></li>
|
||||
</ul>
|
||||
</div><!-- end #main-->
|
||||
|
||||
|
@ -1,59 +1,63 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<div class="col-mb-12 col-offset-1 col-3 kit-hidden-tb" id="secondary" role="complementary">
|
||||
<?php if (!empty($this->options->sidebarBlock) && in_array('ShowRecentPosts', $this->options->sidebarBlock)): ?>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('最新文章'); ?></h3>
|
||||
<ul class="widget-list">
|
||||
<?php $this->widget('Widget_Contents_Post_Recent')
|
||||
->parse('<li><a href="{permalink}">{title}</a></li>'); ?>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('最新文章'); ?></h3>
|
||||
<ul class="widget-list">
|
||||
<?php \Widget\Contents\Post\Recent::alloc()
|
||||
->parse('<li><a href="{permalink}">{title}</a></li>'); ?>
|
||||
</ul>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($this->options->sidebarBlock) && in_array('ShowRecentComments', $this->options->sidebarBlock)): ?>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('最近回复'); ?></h3>
|
||||
<ul class="widget-list">
|
||||
<?php $this->widget('Widget_Comments_Recent')->to($comments); ?>
|
||||
<?php while($comments->next()): ?>
|
||||
<li><a href="<?php $comments->permalink(); ?>"><?php $comments->author(false); ?></a>: <?php $comments->excerpt(35, '...'); ?></li>
|
||||
<?php endwhile; ?>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('最近回复'); ?></h3>
|
||||
<ul class="widget-list">
|
||||
<?php \Widget\Comments\Recent::alloc()->to($comments); ?>
|
||||
<?php while ($comments->next()): ?>
|
||||
<li>
|
||||
<a href="<?php $comments->permalink(); ?>"><?php $comments->author(false); ?></a>: <?php $comments->excerpt(35, '...'); ?>
|
||||
</li>
|
||||
<?php endwhile; ?>
|
||||
</ul>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($this->options->sidebarBlock) && in_array('ShowCategory', $this->options->sidebarBlock)): ?>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('分类'); ?></h3>
|
||||
<?php $this->widget('Widget_Metas_Category_List')->listCategories('wrapClass=widget-list'); ?>
|
||||
</section>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('分类'); ?></h3>
|
||||
<?php \Widget\Metas\Category\Rows::alloc()->listCategories('wrapClass=widget-list'); ?>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($this->options->sidebarBlock) && in_array('ShowArchive', $this->options->sidebarBlock)): ?>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('归档'); ?></h3>
|
||||
<ul class="widget-list">
|
||||
<?php $this->widget('Widget_Contents_Post_Date', 'type=month&format=F Y')
|
||||
->parse('<li><a href="{permalink}">{date}</a></li>'); ?>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('归档'); ?></h3>
|
||||
<ul class="widget-list">
|
||||
<?php \Widget\Contents\Post\Date::alloc('type=month&format=F Y')
|
||||
->parse('<li><a href="{permalink}">{date}</a></li>'); ?>
|
||||
</ul>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($this->options->sidebarBlock) && in_array('ShowOther', $this->options->sidebarBlock)): ?>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('其它'); ?></h3>
|
||||
<ul class="widget-list">
|
||||
<?php if($this->user->hasLogin()): ?>
|
||||
<li class="last"><a href="<?php $this->options->adminUrl(); ?>"><?php _e('进入后台'); ?> (<?php $this->user->screenName(); ?>)</a></li>
|
||||
<li><a href="<?php $this->options->logoutUrl(); ?>"><?php _e('退出'); ?></a></li>
|
||||
<?php else: ?>
|
||||
<li class="last"><a href="<?php $this->options->adminUrl('login.php'); ?>"><?php _e('登录'); ?></a></li>
|
||||
<?php endif; ?>
|
||||
<li><a href="<?php $this->options->feedUrl(); ?>"><?php _e('文章 RSS'); ?></a></li>
|
||||
<li><a href="<?php $this->options->commentsFeedUrl(); ?>"><?php _e('评论 RSS'); ?></a></li>
|
||||
<li><a href="http://www.typecho.org">Typecho</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="widget">
|
||||
<h3 class="widget-title"><?php _e('其它'); ?></h3>
|
||||
<ul class="widget-list">
|
||||
<?php if ($this->user->hasLogin()): ?>
|
||||
<li class="last"><a href="<?php $this->options->adminUrl(); ?>"><?php _e('进入后台'); ?>
|
||||
(<?php $this->user->screenName(); ?>)</a></li>
|
||||
<li><a href="<?php $this->options->logoutUrl(); ?>"><?php _e('退出'); ?></a></li>
|
||||
<?php else: ?>
|
||||
<li class="last"><a href="<?php $this->options->adminUrl('login.php'); ?>"><?php _e('登录'); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<li><a href="<?php $this->options->feedUrl(); ?>"><?php _e('文章 RSS'); ?></a></li>
|
||||
<li><a href="<?php $this->options->commentsFeedUrl(); ?>"><?php _e('评论 RSS'); ?></a></li>
|
||||
<li><a href="http://www.typecho.org">Typecho</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
</div><!-- end #sidebar -->
|
||||
|
@ -98,18 +98,6 @@ textarea {
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.browsehappy {
|
||||
padding: 8px 0;
|
||||
background: #FBE3E4;
|
||||
color: #8A1F11;
|
||||
text-align: center;
|
||||
}
|
||||
.browsehappy a {
|
||||
color: #8A1F11;
|
||||
text-decoration: underline;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* ------------------
|
||||
* Header
|
||||
* --------------- */
|
||||
|
@ -1,18 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
|
||||
Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
|
||||
Site: http://scripts.incutio.com/xmlrpc/
|
||||
Manual: http://scripts.incutio.com/xmlrpc/manual.php
|
||||
Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
|
||||
*/
|
||||
|
||||
namespace IXR;
|
||||
|
||||
/**
|
||||
* IXR Base64编码
|
||||
*
|
||||
* @package IXR
|
||||
*/
|
||||
class IXR_Base64
|
||||
class Base64
|
||||
{
|
||||
/**
|
||||
* 编码数据
|
||||
@ -26,7 +21,7 @@ class IXR_Base64
|
||||
*
|
||||
* @param string $data
|
||||
*/
|
||||
public function __construct($data)
|
||||
public function __construct(string $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
@ -1,11 +1,8 @@
|
||||
<?php
|
||||
/*
|
||||
IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
|
||||
Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
|
||||
Site: http://scripts.incutio.com/xmlrpc/
|
||||
Manual: http://scripts.incutio.com/xmlrpc/manual.php
|
||||
Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
|
||||
*/
|
||||
|
||||
namespace IXR;
|
||||
|
||||
use Typecho\Http\Client as HttpClient;
|
||||
|
||||
/**
|
||||
* IXR客户端
|
||||
@ -13,71 +10,28 @@
|
||||
*
|
||||
* @package IXR
|
||||
*/
|
||||
class IXR_Client
|
||||
class Client
|
||||
{
|
||||
/** 默认客户端 */
|
||||
const DEFAULT_USERAGENT = 'The Incutio XML-RPC PHP Library(Reload By Typecho)';
|
||||
|
||||
/**
|
||||
* 服务端地址
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $server;
|
||||
|
||||
/**
|
||||
* 端口名称
|
||||
*
|
||||
* @access private
|
||||
* @var integer
|
||||
*/
|
||||
private $port;
|
||||
|
||||
/**
|
||||
* 路径名称
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
private const DEFAULT_USERAGENT = 'Typecho XML-RPC PHP Library';
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* 客户端
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $useragent;
|
||||
|
||||
/**
|
||||
* 回执结构体
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* 消息体
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
* @var Message
|
||||
*/
|
||||
private $message = false;
|
||||
private $message;
|
||||
|
||||
/**
|
||||
* 调试开关
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $debug = false;
|
||||
@ -85,66 +39,35 @@ class IXR_Client
|
||||
/**
|
||||
* 请求前缀
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
private $prefix = NULL;
|
||||
private $prefix;
|
||||
|
||||
// Storage place for an error message
|
||||
private $error = false;
|
||||
/**
|
||||
* @var Error
|
||||
*/
|
||||
private $error;
|
||||
|
||||
/**
|
||||
* 客户端构造函数
|
||||
*
|
||||
* @access public
|
||||
* @param string $server 服务端地址
|
||||
* @param string $path 路径名称
|
||||
* @param integer $port 端口名称
|
||||
* @param string $useragent 客户端
|
||||
* @param string $url 服务端地址
|
||||
* @param string|null $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($server, $path = false, $port = 80, $useragent = self::DEFAULT_USERAGENT, $prefix = NULL)
|
||||
{
|
||||
if (!$path) {
|
||||
$this->url = $server;
|
||||
|
||||
// Assume we have been given a Url instead
|
||||
$bits = parse_url($server);
|
||||
$this->server = $bits['host'];
|
||||
$this->port = isset($bits['port']) ? $bits['port'] : 80;
|
||||
$this->path = isset($bits['path']) ? $bits['path'] : '/';
|
||||
|
||||
// Make absolutely sure we have a path
|
||||
if (isset($bits['query'])) {
|
||||
$this->path .= '?' . $bits['query'];
|
||||
}
|
||||
} else {
|
||||
/** Typecho_Common */
|
||||
require_once 'Typecho/Common.php';
|
||||
|
||||
$this->url = Typecho_Common::buildUrl(array(
|
||||
'scheme' => 'http',
|
||||
'host' => $server,
|
||||
'path' => $path,
|
||||
'port' => $port
|
||||
));
|
||||
|
||||
$this->server = $server;
|
||||
$this->path = $path;
|
||||
$this->port = $port;
|
||||
}
|
||||
|
||||
public function __construct(
|
||||
string $url,
|
||||
?string $prefix = null
|
||||
) {
|
||||
$this->url = $url;
|
||||
$this->prefix = $prefix;
|
||||
$this->useragent = $useragent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置调试模式
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @deprecated
|
||||
*/
|
||||
public function __setDebug()
|
||||
public function setDebug()
|
||||
{
|
||||
$this->debug = true;
|
||||
}
|
||||
@ -152,44 +75,48 @@ class IXR_Client
|
||||
/**
|
||||
* 执行请求
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @return bool
|
||||
*/
|
||||
public function __rpcCall()
|
||||
private function rpcCall(string $method, array $args): bool
|
||||
{
|
||||
$args = func_get_args();
|
||||
$method = array_shift($args);
|
||||
$request = new IXR_Request($method, $args);
|
||||
$request = new Request($method, $args);
|
||||
$xml = $request->getXml();
|
||||
|
||||
$client = Typecho_Http_Client::get();
|
||||
$client = HttpClient::get();
|
||||
if (!$client) {
|
||||
$this->error = new IXR_Error(-32300, 'transport error - could not open socket');
|
||||
$this->error = new Error(-32300, 'transport error - could not open socket');
|
||||
return false;
|
||||
}
|
||||
|
||||
$client->setHeader('Content-Type', 'text/xml')
|
||||
->setHeader('User-Agent', $this->useragent)
|
||||
->setData($xml)
|
||||
->send($this->url);
|
||||
try {
|
||||
$client->setHeader('Content-Type', 'text/xml')
|
||||
->setHeader('User-Agent', self::DEFAULT_USERAGENT)
|
||||
->setData($xml)
|
||||
->send($this->url);
|
||||
} catch (HttpClient\Exception $e) {
|
||||
$this->error = new Error(-32700, $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
$contents = $client->getResponseBody();
|
||||
|
||||
if ($this->debug) {
|
||||
echo '<pre>'.htmlspecialchars($contents)."\n</pre>\n\n";
|
||||
echo '<pre>' . htmlspecialchars($contents) . "\n</pre>\n\n";
|
||||
}
|
||||
|
||||
// Now parse what we've got back
|
||||
$this->message = new IXR_Message($contents);
|
||||
$this->message = new Message($contents);
|
||||
if (!$this->message->parse()) {
|
||||
// XML error
|
||||
$this->error = new IXR_Error(-32700, 'parse error. not well formed');
|
||||
$this->error = new Error(-32700, 'parse error. not well formed');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is the message a fault?
|
||||
if ($this->message->messageType == 'fault') {
|
||||
$this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
|
||||
$this->error = new Error($this->message->faultCode, $this->message->faultString);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -203,42 +130,38 @@ class IXR_Client
|
||||
* $rpc->metaWeblog->newPost();
|
||||
* </code>
|
||||
*
|
||||
* @access public
|
||||
* @param string $prefix 前缀
|
||||
* @return IXR_Client
|
||||
* @return Client
|
||||
*/
|
||||
public function __get($prefix)
|
||||
public function __get(string $prefix): Client
|
||||
{
|
||||
return new IXR_Client($this->server, $this->path, $this->port, $this->useragent, $this->prefix . $prefix . '.');
|
||||
return new self($this->url, $this->prefix . $prefix . '.');
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加魔术特性
|
||||
* by 70
|
||||
*
|
||||
* @access public
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
array_unshift($args, $this->prefix . $method);
|
||||
$return = call_user_func_array(array($this, '__rpcCall'), $args);
|
||||
$return = $this->rpcCall($this->prefix . $method, $args);
|
||||
|
||||
if ($return) {
|
||||
return $this->__getResponse();
|
||||
return $this->getResponse();
|
||||
} else {
|
||||
require_once 'IXR/Exception.php';
|
||||
throw new IXR_Exception($this->__getErrorMessage(), $this->__getErrorCode());
|
||||
throw new Exception($this->getErrorMessage(), $this->getErrorCode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得返回值
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @return mixed
|
||||
*/
|
||||
public function __getResponse()
|
||||
public function getResponse()
|
||||
{
|
||||
// methodResponses can only have one param - return that
|
||||
return $this->message->params[0];
|
||||
@ -247,21 +170,19 @@ class IXR_Client
|
||||
/**
|
||||
* 是否为错误
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function __isError()
|
||||
public function isError(): bool
|
||||
{
|
||||
return (is_object($this->error));
|
||||
return isset($this->error);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取错误代码
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function __getErrorCode()
|
||||
private function getErrorCode(): int
|
||||
{
|
||||
return $this->error->code;
|
||||
}
|
||||
@ -269,10 +190,9 @@ class IXR_Client
|
||||
/**
|
||||
* 获取错误消息
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @return string
|
||||
*/
|
||||
public function __getErrorMessage()
|
||||
private function getErrorMessage(): string
|
||||
{
|
||||
return $this->error->message;
|
||||
}
|
||||
|
@ -1,33 +1,44 @@
|
||||
<?php
|
||||
/*
|
||||
IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
|
||||
Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
|
||||
Site: http://scripts.incutio.com/xmlrpc/
|
||||
Manual: http://scripts.incutio.com/xmlrpc/manual.php
|
||||
Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
|
||||
*/
|
||||
|
||||
namespace IXR;
|
||||
|
||||
/**
|
||||
* IXR日期
|
||||
*
|
||||
* @package IXR
|
||||
*/
|
||||
class IXR_Date {
|
||||
var $year;
|
||||
var $month;
|
||||
var $day;
|
||||
var $hour;
|
||||
var $minute;
|
||||
var $second;
|
||||
function __construct($time) {
|
||||
class Date
|
||||
{
|
||||
private $year;
|
||||
|
||||
private $month;
|
||||
|
||||
private $day;
|
||||
|
||||
private $hour;
|
||||
|
||||
private $minute;
|
||||
|
||||
private $second;
|
||||
|
||||
/**
|
||||
* @param int|string $time
|
||||
*/
|
||||
public function __construct($time)
|
||||
{
|
||||
// $time can be a PHP timestamp or an ISO one
|
||||
if (is_numeric($time)) {
|
||||
$this->parseTimestamp($time);
|
||||
$this->parseTimestamp(intval($time));
|
||||
} else {
|
||||
$this->parseIso($time);
|
||||
}
|
||||
}
|
||||
function parseTimestamp($timestamp) {
|
||||
|
||||
/**
|
||||
* @param int $timestamp
|
||||
*/
|
||||
private function parseTimestamp(int $timestamp)
|
||||
{
|
||||
$this->year = date('Y', $timestamp);
|
||||
$this->month = date('m', $timestamp);
|
||||
$this->day = date('d', $timestamp);
|
||||
@ -35,7 +46,12 @@ class IXR_Date {
|
||||
$this->minute = date('i', $timestamp);
|
||||
$this->second = date('s', $timestamp);
|
||||
}
|
||||
function parseIso($iso) {
|
||||
|
||||
/**
|
||||
* @param string $iso
|
||||
*/
|
||||
private function parseIso(string $iso)
|
||||
{
|
||||
$this->year = substr($iso, 0, 4);
|
||||
$this->month = substr($iso, 4, 2);
|
||||
$this->day = substr($iso, 6, 2);
|
||||
@ -43,13 +59,28 @@ class IXR_Date {
|
||||
$this->minute = substr($iso, 12, 2);
|
||||
$this->second = substr($iso, 15, 2);
|
||||
}
|
||||
function getIso() {
|
||||
return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIso(): string
|
||||
{
|
||||
return $this->year . $this->month . $this->day . 'T' . $this->hour . ':' . $this->minute . ':' . $this->second;
|
||||
}
|
||||
function getXml() {
|
||||
return '<dateTime.iso8601>'.$this->getIso().'</dateTime.iso8601>';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getXml(): string
|
||||
{
|
||||
return '<dateTime.iso8601>' . $this->getIso() . '</dateTime.iso8601>';
|
||||
}
|
||||
function getTimestamp() {
|
||||
|
||||
/**
|
||||
* @return false|int
|
||||
*/
|
||||
public function getTimestamp()
|
||||
{
|
||||
return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
|
||||
Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
|
||||
Site: http://scripts.incutio.com/xmlrpc/
|
||||
Manual: http://scripts.incutio.com/xmlrpc/manual.php
|
||||
Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
|
||||
*/
|
||||
|
||||
namespace IXR;
|
||||
|
||||
/**
|
||||
* IXR错误
|
||||
*
|
||||
* @package IXR
|
||||
*/
|
||||
class IXR_Error
|
||||
class Error
|
||||
{
|
||||
/**
|
||||
* 错误代码
|
||||
@ -26,19 +21,17 @@ class IXR_Error
|
||||
* 错误消息
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @access public
|
||||
* @param integer $code 错误代码
|
||||
* @param string $message 错误消息
|
||||
* @return void
|
||||
* @param string|null $message 错误消息
|
||||
*/
|
||||
public function __construct($code, $message)
|
||||
public function __construct(int $code, ?string $message)
|
||||
{
|
||||
$this->code = $code;
|
||||
$this->message = $message;
|
||||
@ -47,12 +40,11 @@ class IXR_Error
|
||||
/**
|
||||
* 获取xml
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getXml()
|
||||
public function getXml(): string
|
||||
{
|
||||
$xml = <<<EOD
|
||||
return <<<EOD
|
||||
<methodResponse>
|
||||
<fault>
|
||||
<value>
|
||||
@ -71,6 +63,5 @@ class IXR_Error
|
||||
</methodResponse>
|
||||
|
||||
EOD;
|
||||
return $xml;
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,12 @@
|
||||
<?php
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
/*
|
||||
IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
|
||||
Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
|
||||
Site: http://scripts.incutio.com/xmlrpc/
|
||||
Manual: http://scripts.incutio.com/xmlrpc/manual.php
|
||||
Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
|
||||
*/
|
||||
|
||||
namespace IXR;
|
||||
|
||||
/**
|
||||
* IXR异常类
|
||||
*
|
||||
* @package IXR
|
||||
*/
|
||||
class IXR_Exception extends Exception
|
||||
{}
|
||||
class Exception extends \Exception
|
||||
{
|
||||
}
|
||||
|
25
var/IXR/Hook.php
Normal file
25
var/IXR/Hook.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace IXR;
|
||||
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* hook rpc call
|
||||
*/
|
||||
interface Hook
|
||||
{
|
||||
/**
|
||||
* @param string $methodName
|
||||
* @param ReflectionMethod $reflectionMethod
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function beforeRpcCall(string $methodName, ReflectionMethod $reflectionMethod, array $parameters);
|
||||
|
||||
/**
|
||||
* @param string $methodName
|
||||
* @param mixed $result
|
||||
*/
|
||||
public function afterRpcCall(string $methodName, &$result): void;
|
||||
}
|
@ -1,57 +1,79 @@
|
||||
<?php
|
||||
/*
|
||||
IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
|
||||
Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
|
||||
Site: http://scripts.incutio.com/xmlrpc/
|
||||
Manual: http://scripts.incutio.com/xmlrpc/manual.php
|
||||
Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
|
||||
*/
|
||||
|
||||
namespace IXR;
|
||||
|
||||
/**
|
||||
* IXR消息
|
||||
*
|
||||
* @package IXR
|
||||
*/
|
||||
class IXR_Message {
|
||||
var $message;
|
||||
var $messageType; // methodCall / methodResponse / fault
|
||||
var $faultCode;
|
||||
var $faultString;
|
||||
var $methodName;
|
||||
var $params;
|
||||
class Message
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $messageType; // methodCall / methodResponse / fault
|
||||
|
||||
public $faultCode;
|
||||
|
||||
public $faultString;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $methodName;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $params = [];
|
||||
|
||||
// Current variable stacks
|
||||
var $_arraystructs = array(); // The stack used to keep track of the current array/struct
|
||||
var $_arraystructstypes = array(); // Stack keeping track of if things are structs or array
|
||||
var $_currentStructName = array(); // A stack as well
|
||||
var $_param;
|
||||
var $_value;
|
||||
var $_currentTag;
|
||||
var $_currentTagContents;
|
||||
// The XML parser
|
||||
var $_parser;
|
||||
function __construct ($message) {
|
||||
private $arrayStructs = []; // The stack used to keep track of the current array/struct
|
||||
|
||||
private $arrayStructsTypes = []; // Stack keeping track of if things are structs or array
|
||||
|
||||
private $currentStructName = []; // A stack as well
|
||||
|
||||
private $currentTagContents;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*/
|
||||
public function __construct(string $message)
|
||||
{
|
||||
$this->message = $message;
|
||||
}
|
||||
function parse() {
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function parse(): bool
|
||||
{
|
||||
// first remove the XML declaration
|
||||
$this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message);
|
||||
$this->message = preg_replace('/<\?xml(.*)?\?' . '>/', '', $this->message);
|
||||
if (trim($this->message) == '') {
|
||||
return false;
|
||||
}
|
||||
$this->_parser = xml_parser_create();
|
||||
$parser = xml_parser_create();
|
||||
// Set XML parser to take the case of tags in to account
|
||||
xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
|
||||
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
|
||||
// Set XML parser callback functions
|
||||
xml_set_object($this->_parser, $this);
|
||||
xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
|
||||
xml_set_character_data_handler($this->_parser, 'cdata');
|
||||
if (!xml_parse($this->_parser, $this->message)) {
|
||||
xml_set_object($parser, $this);
|
||||
xml_set_element_handler($parser, [$this, 'tagOpen'], [$this, 'tagClose']);
|
||||
xml_set_character_data_handler($parser, [$this, 'cdata']);
|
||||
if (!xml_parse($parser, $this->message)) {
|
||||
/* die(sprintf('XML error: %s at line %d',
|
||||
xml_error_string(xml_get_error_code($this->_parser)),
|
||||
xml_get_current_line_number($this->_parser))); */
|
||||
xml_error_string(xml_get_error_code($this->parser)),
|
||||
xml_get_current_line_number($this->parser))); */
|
||||
return false;
|
||||
}
|
||||
xml_parser_free($this->_parser);
|
||||
xml_parser_free($parser);
|
||||
// Grab the error messages, if any
|
||||
if ($this->messageType == 'fault') {
|
||||
$this->faultCode = $this->params[0]['faultCode'];
|
||||
@ -59,9 +81,15 @@ class IXR_Message {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function tag_open($parser, $tag, $attr) {
|
||||
$this->currentTag = $tag;
|
||||
switch($tag) {
|
||||
|
||||
/**
|
||||
* @param $parser
|
||||
* @param $tag
|
||||
* @param $attr
|
||||
*/
|
||||
private function tagOpen($parser, string $tag, $attr)
|
||||
{
|
||||
switch ($tag) {
|
||||
case 'methodCall':
|
||||
case 'methodResponse':
|
||||
case 'fault':
|
||||
@ -69,94 +97,98 @@ class IXR_Message {
|
||||
break;
|
||||
/* Deal with stacks of arrays and structs */
|
||||
case 'data': // data is to all intents and puposes more interesting than array
|
||||
$this->_arraystructstypes[] = 'array';
|
||||
$this->_arraystructs[] = array();
|
||||
$this->arrayStructsTypes[] = 'array';
|
||||
$this->arrayStructs[] = [];
|
||||
break;
|
||||
case 'struct':
|
||||
$this->_arraystructstypes[] = 'struct';
|
||||
$this->_arraystructs[] = array();
|
||||
$this->arrayStructsTypes[] = 'struct';
|
||||
$this->arrayStructs[] = [];
|
||||
break;
|
||||
}
|
||||
}
|
||||
function cdata($parser, $cdata) {
|
||||
$this->_currentTagContents .= $cdata;
|
||||
|
||||
/**
|
||||
* @param $parser
|
||||
* @param string $cdata
|
||||
*/
|
||||
private function cdata($parser, string $cdata)
|
||||
{
|
||||
$this->currentTagContents .= $cdata;
|
||||
}
|
||||
function tag_close($parser, $tag) {
|
||||
$valueFlag = false;
|
||||
switch($tag) {
|
||||
|
||||
/**
|
||||
* @param $parser
|
||||
* @param string $tag
|
||||
*/
|
||||
private function tagClose($parser, string $tag)
|
||||
{
|
||||
switch ($tag) {
|
||||
case 'int':
|
||||
case 'i4':
|
||||
$value = (int)trim($this->_currentTagContents);
|
||||
$this->_currentTagContents = '';
|
||||
$valueFlag = true;
|
||||
$value = (int) trim($this->currentTagContents);
|
||||
$this->currentTagContents = '';
|
||||
break;
|
||||
case 'double':
|
||||
$value = (double)trim($this->_currentTagContents);
|
||||
$this->_currentTagContents = '';
|
||||
$valueFlag = true;
|
||||
$value = (double) trim($this->currentTagContents);
|
||||
$this->currentTagContents = '';
|
||||
break;
|
||||
case 'string':
|
||||
$value = (string)trim($this->_currentTagContents);
|
||||
$this->_currentTagContents = '';
|
||||
$valueFlag = true;
|
||||
$value = (string)trim($this->currentTagContents);
|
||||
$this->currentTagContents = '';
|
||||
break;
|
||||
case 'dateTime.iso8601':
|
||||
$value = new IXR_Date(trim($this->_currentTagContents));
|
||||
$value = new Date(trim($this->currentTagContents));
|
||||
// $value = $iso->getTimestamp();
|
||||
$this->_currentTagContents = '';
|
||||
$valueFlag = true;
|
||||
$this->currentTagContents = '';
|
||||
break;
|
||||
case 'value':
|
||||
// "If no type is indicated, the type is string."
|
||||
if (trim($this->_currentTagContents) != '') {
|
||||
$value = (string)$this->_currentTagContents;
|
||||
$this->_currentTagContents = '';
|
||||
$valueFlag = true;
|
||||
if (trim($this->currentTagContents) != '') {
|
||||
$value = (string) $this->currentTagContents;
|
||||
$this->currentTagContents = '';
|
||||
}
|
||||
break;
|
||||
case 'boolean':
|
||||
$value = (boolean)trim($this->_currentTagContents);
|
||||
$this->_currentTagContents = '';
|
||||
$valueFlag = true;
|
||||
$value = (bool) trim($this->currentTagContents);
|
||||
$this->currentTagContents = '';
|
||||
break;
|
||||
case 'base64':
|
||||
$value = base64_decode($this->_currentTagContents);
|
||||
$this->_currentTagContents = '';
|
||||
$valueFlag = true;
|
||||
$value = base64_decode($this->currentTagContents);
|
||||
$this->currentTagContents = '';
|
||||
break;
|
||||
/* Deal with stacks of arrays and structs */
|
||||
case 'data':
|
||||
case 'struct':
|
||||
$value = array_pop($this->_arraystructs);
|
||||
array_pop($this->_arraystructstypes);
|
||||
$valueFlag = true;
|
||||
$value = array_pop($this->arrayStructs);
|
||||
array_pop($this->arrayStructsTypes);
|
||||
break;
|
||||
case 'member':
|
||||
array_pop($this->_currentStructName);
|
||||
array_pop($this->currentStructName);
|
||||
break;
|
||||
case 'name':
|
||||
$this->_currentStructName[] = trim($this->_currentTagContents);
|
||||
$this->_currentTagContents = '';
|
||||
$this->currentStructName[] = trim($this->currentTagContents);
|
||||
$this->currentTagContents = '';
|
||||
break;
|
||||
case 'methodName':
|
||||
$this->methodName = trim($this->_currentTagContents);
|
||||
$this->_currentTagContents = '';
|
||||
$this->methodName = trim($this->currentTagContents);
|
||||
$this->currentTagContents = '';
|
||||
break;
|
||||
}
|
||||
if ($valueFlag) {
|
||||
if (isset($value)) {
|
||||
/*
|
||||
if (!is_array($value) && !is_object($value)) {
|
||||
$value = trim($value);
|
||||
}
|
||||
*/
|
||||
if (count($this->_arraystructs) > 0) {
|
||||
if (count($this->arrayStructs) > 0) {
|
||||
// Add value to struct or array
|
||||
if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') {
|
||||
if ($this->arrayStructsTypes[count($this->arrayStructsTypes) - 1] == 'struct') {
|
||||
// Add to struct
|
||||
$this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value;
|
||||
$this->arrayStructs[count($this->arrayStructs) - 1]
|
||||
[$this->currentStructName[count($this->currentStructName) - 1]] = $value;
|
||||
} else {
|
||||
// Add to array
|
||||
$this->_arraystructs[count($this->_arraystructs)-1][] = $value;
|
||||
$this->arrayStructs[count($this->arrayStructs) - 1][] = $value;
|
||||
}
|
||||
} else {
|
||||
// Just add as a paramater
|
||||
|
120
var/IXR/Pingback.php
Normal file
120
var/IXR/Pingback.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace IXR;
|
||||
|
||||
use Typecho\Common;
|
||||
use Typecho\Http\Client as HttpClient;
|
||||
use Typecho\Http\Client\Exception as HttpException;
|
||||
|
||||
/**
|
||||
* fetch pingback
|
||||
*/
|
||||
class Pingback
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $html;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $target;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $target
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(string $url, string $target)
|
||||
{
|
||||
$client = HttpClient::get();
|
||||
$this->target = $target;
|
||||
|
||||
if (!isset($client)) {
|
||||
throw new Exception('No available http client', 50);
|
||||
}
|
||||
|
||||
try {
|
||||
$client->setTimeout(5)
|
||||
->send($url);
|
||||
} catch (HttpException $e) {
|
||||
throw new Exception('Pingback http error', 50);
|
||||
}
|
||||
|
||||
if ($client->getResponseStatus() != 200) {
|
||||
throw new Exception('Pingback wrong http status', 50);
|
||||
}
|
||||
|
||||
$response = $client->getResponseBody();
|
||||
$encoding = 'UTF-8';
|
||||
$contentType = $client->getResponseHeader('Content-Type');
|
||||
|
||||
if (!empty($contentType) && preg_match("/charset=([_a-z0-9-]+)/i", $contentType, $matches)) {
|
||||
$encoding = strtoupper($matches[1]);
|
||||
} elseif (preg_match("/<meta\s+charset=\"([_a-z0-9-]+)\"/i", $response, $matches)) {
|
||||
$encoding = strtoupper($matches[1]);
|
||||
}
|
||||
|
||||
$this->html = $encoding == 'UTF-8' ? $response : mb_convert_encoding($response, 'UTF-8', $encoding);
|
||||
|
||||
if (
|
||||
!$client->getResponseHeader('X-Pingback') &&
|
||||
!preg_match_all("/<link[^>]*rel=[\"']pingback[\"'][^>]+href=[\"']([^\"']*)[\"'][^>]*>/i", $this->html)
|
||||
) {
|
||||
throw new Exception("Source server doesn't support pingback", 50);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
if (preg_match("/\<title\>([^<]*?)\<\/title\\>/is", $this->html, $matchTitle)) {
|
||||
return Common::subStr(Common::removeXSS(trim(strip_tags($matchTitle[1]))), 0, 150, '...');
|
||||
}
|
||||
|
||||
return parse_url($this->target, PHP_URL_HOST);
|
||||
}
|
||||
|
||||
/**
|
||||
* get content
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getContent(): string
|
||||
{
|
||||
/** 干掉html tag,只留下<a>*/
|
||||
$text = Common::stripTags($this->html, '<a href="">');
|
||||
|
||||
/** 此处将$target quote,留着后面用*/
|
||||
$pregLink = preg_quote($this->target);
|
||||
|
||||
/** 找出含有target链接的最长的一行作为$finalText*/
|
||||
$finalText = null;
|
||||
$lines = explode("\n", $text);
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
if (null != $line) {
|
||||
if (preg_match("|<a[^>]*href=[\"']{$pregLink}[\"'][^>]*>(.*?)</a>|", $line)) {
|
||||
if (strlen($line) > strlen($finalText)) {
|
||||
/** <a>也要干掉,*/
|
||||
$finalText = Common::stripTags($line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($finalText)) {
|
||||
throw new Exception("Source page doesn't have target url", 50);
|
||||
}
|
||||
|
||||
return '[...]' . Common::subStr($finalText, 0, 200, '') . '[...]';
|
||||
}
|
||||
}
|
@ -1,43 +1,55 @@
|
||||
<?php
|
||||
/*
|
||||
IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
|
||||
Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
|
||||
Site: http://scripts.incutio.com/xmlrpc/
|
||||
Manual: http://scripts.incutio.com/xmlrpc/manual.php
|
||||
Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
|
||||
*/
|
||||
|
||||
namespace IXR;
|
||||
|
||||
/**
|
||||
* IXR请求体
|
||||
*
|
||||
* @package IXR
|
||||
*/
|
||||
class IXR_Request {
|
||||
var $method;
|
||||
var $args;
|
||||
var $xml;
|
||||
function __construct($method, $args) {
|
||||
$this->method = $method;
|
||||
$this->args = $args;
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $xml;
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct(string $method, array $args)
|
||||
{
|
||||
$this->xml = <<<EOD
|
||||
<?xml version="1.0"?>
|
||||
<methodCall>
|
||||
<methodName>{$this->method}</methodName>
|
||||
<methodName>{$method}</methodName>
|
||||
<params>
|
||||
|
||||
EOD;
|
||||
foreach ($this->args as $arg) {
|
||||
foreach ($args as $arg) {
|
||||
$this->xml .= '<param><value>';
|
||||
$v = new IXR_Value($arg);
|
||||
$v = new Value($arg);
|
||||
$this->xml .= $v->getXml();
|
||||
$this->xml .= "</value></param>\n";
|
||||
}
|
||||
|
||||
$this->xml .= '</params></methodCall>';
|
||||
}
|
||||
function getLength() {
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLength(): int
|
||||
{
|
||||
return strlen($this->xml);
|
||||
}
|
||||
function getXml() {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getXml(): string
|
||||
{
|
||||
return $this->xml;
|
||||
}
|
||||
}
|
||||
|
@ -1,137 +1,228 @@
|
||||
<?php
|
||||
/*
|
||||
IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
|
||||
Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
|
||||
Site: http://scripts.incutio.com/xmlrpc/
|
||||
Manual: http://scripts.incutio.com/xmlrpc/manual.php
|
||||
Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
|
||||
*/
|
||||
|
||||
namespace IXR;
|
||||
|
||||
use Typecho\Widget\Exception as WidgetException;
|
||||
|
||||
/**
|
||||
* IXR服务器
|
||||
*
|
||||
* @package IXR
|
||||
*/
|
||||
class IXR_Server
|
||||
class Server
|
||||
{
|
||||
/**
|
||||
* 输入参数
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* 回调函数
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $callbacks = array();
|
||||
|
||||
/**
|
||||
* 消息体
|
||||
*
|
||||
* @access private
|
||||
* @var IXR_Message
|
||||
*/
|
||||
private $message;
|
||||
private $callbacks;
|
||||
|
||||
/**
|
||||
* 默认参数
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $capabilities;
|
||||
|
||||
/**
|
||||
* @var Hook
|
||||
*/
|
||||
private $hook;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $callbacks 回调函数
|
||||
* @param mixed $data 输入参数
|
||||
* @return void
|
||||
* @param array $callbacks 回调函数
|
||||
*/
|
||||
public function __construct($callbacks = false, $data = false)
|
||||
public function __construct(array $callbacks = [])
|
||||
{
|
||||
$this->setCapabilities();
|
||||
if ($callbacks) {
|
||||
$this->callbacks = $callbacks;
|
||||
}
|
||||
$this->callbacks = $callbacks;
|
||||
$this->setCallbacks();
|
||||
$this->serve($data);
|
||||
$this->serve();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认参数
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCapabilities(): array
|
||||
{
|
||||
return $this->capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出所有方法
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function listMethods(): array
|
||||
{
|
||||
// Returns a list of methods - uses array_reverse to ensure user defined
|
||||
// methods are listed before server defined methods
|
||||
return array_reverse(array_keys($this->callbacks));
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次处理多个请求
|
||||
*
|
||||
* @param array $methodcalls
|
||||
* @return array
|
||||
*/
|
||||
public function multiCall(array $methodcalls): array
|
||||
{
|
||||
// See http://www.xmlrpc.com/discuss/msgReader$1208
|
||||
$return = [];
|
||||
foreach ($methodcalls as $call) {
|
||||
$method = $call['methodName'];
|
||||
$params = $call['params'];
|
||||
if ($method == 'system.multicall') {
|
||||
$result = new Error(-32600, 'Recursive calls to system.multicall are forbidden');
|
||||
} else {
|
||||
$result = $this->call($method, $params);
|
||||
}
|
||||
if (is_a($result, 'Error')) {
|
||||
$return[] = [
|
||||
'faultCode' => $result->code,
|
||||
'faultString' => $result->message
|
||||
];
|
||||
} else {
|
||||
$return[] = [$result];
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $methodName
|
||||
* @return string|Error
|
||||
*/
|
||||
public function methodHelp(string $methodName)
|
||||
{
|
||||
if (!$this->hasMethod($methodName)) {
|
||||
return new Error(-32601, 'server error. requested method ' . $methodName . ' does not exist.');
|
||||
}
|
||||
|
||||
[$object, $method] = $this->callbacks[$methodName];
|
||||
|
||||
try {
|
||||
$ref = new \ReflectionMethod($object, $method);
|
||||
$doc = $ref->getDocComment();
|
||||
|
||||
return $doc ?: '';
|
||||
} catch (\ReflectionException $e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Hook $hook
|
||||
*/
|
||||
public function setHook(Hook $hook)
|
||||
{
|
||||
$this->hook = $hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* 呼叫内部方法
|
||||
*
|
||||
* @access private
|
||||
* @param string $methodname 方法名
|
||||
* @param mixed $args 参数
|
||||
* @param string $methodName 方法名
|
||||
* @param array $args 参数
|
||||
* @return mixed
|
||||
*/
|
||||
private function call($methodname, $args)
|
||||
private function call(string $methodName, array $args)
|
||||
{
|
||||
// hook
|
||||
if (0 !== strpos($methodname, 'hook.') && $this->hasMethod('hook.beforeCall')) {
|
||||
$this->call('hook.beforeCall', array($methodname));
|
||||
if (!$this->hasMethod($methodName)) {
|
||||
return new Error(-32601, 'server error. requested method ' . $methodName . ' does not exist.');
|
||||
}
|
||||
|
||||
if (!$this->hasMethod($methodname)) {
|
||||
return new IXR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.');
|
||||
}
|
||||
$method = $this->callbacks[$methodname];
|
||||
$method = $this->callbacks[$methodName];
|
||||
|
||||
// Are we dealing with a function or a method?
|
||||
if (is_string($method) && substr($method, 0, 5) == 'this:') {
|
||||
// It's a class method - check it exists
|
||||
$method = substr($method, 5);
|
||||
if (!method_exists($this, $method)) {
|
||||
return new IXR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.');
|
||||
if (!is_callable($method)) {
|
||||
return new Error(
|
||||
-32601,
|
||||
'server error. requested class method "' . $methodName . '" does not exist.'
|
||||
);
|
||||
}
|
||||
|
||||
[$object, $objectMethod] = $method;
|
||||
|
||||
try {
|
||||
$ref = new \ReflectionMethod($object, $objectMethod);
|
||||
$requiredArgs = $ref->getNumberOfRequiredParameters();
|
||||
if (count($args) < $requiredArgs) {
|
||||
return new Error(
|
||||
-32602,
|
||||
'server error. requested class method "' . $methodName . '" require ' . $requiredArgs . ' params.'
|
||||
);
|
||||
}
|
||||
// Call the method
|
||||
$result = $this->$method($args);
|
||||
} else {
|
||||
if (is_array($method)) {
|
||||
list($object, $func) = $method;
|
||||
if (!is_callable($method)) {
|
||||
return new IXR_Error(-32601, 'server error. requested class method "'.$object . '.' . $func.'" does not exist.');
|
||||
|
||||
foreach ($ref->getParameters() as $key => $parameter) {
|
||||
if ($parameter->hasType() && !settype($args[$key], $parameter->getType()->getName())) {
|
||||
return new Error(
|
||||
-32602,
|
||||
'server error. requested class method "'
|
||||
. $methodName . '" ' . $key . ' param has wrong type.'
|
||||
);
|
||||
}
|
||||
|
||||
$result = call_user_func_array(array($object, $func), $args);
|
||||
} elseif (!function_exists($method)) {
|
||||
// It's a function - does it exist?
|
||||
return new IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.');
|
||||
} else {
|
||||
// Call the function
|
||||
$result = $method($args);
|
||||
}
|
||||
|
||||
if (isset($this->hook)) {
|
||||
$result = $this->hook->beforeRpcCall($methodName, $ref, $args);
|
||||
|
||||
if (isset($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
$result = call_user_func_array($method, $args);
|
||||
|
||||
if (isset($this->hook)) {
|
||||
$this->hook->afterRpcCall($methodName, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
} catch (\ReflectionException $e) {
|
||||
return new Error(
|
||||
-32601,
|
||||
'server error. requested class method "' . $methodName . '" does not exist.'
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
return new Error(
|
||||
$e->getCode(),
|
||||
$e->getMessage()
|
||||
);
|
||||
} catch (WidgetException $e) {
|
||||
return new Error(
|
||||
-32001,
|
||||
$e->getMessage()
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
return new Error(
|
||||
-32001,
|
||||
'server error. requested class method "' . $methodName . '" failed.'
|
||||
);
|
||||
}
|
||||
|
||||
// hook
|
||||
if (0 !== strpos($methodname, 'hook.') && $this->hasMethod('hook.afterCall')) {
|
||||
$this->call('hook.afterCall', array($methodname));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 抛出错误
|
||||
*
|
||||
* @access private
|
||||
* @param integer $error 错误代码
|
||||
* @param string $message 错误消息
|
||||
* @param integer|Error $error 错误代码
|
||||
* @param string|null $message 错误消息
|
||||
* @return void
|
||||
*/
|
||||
private function error($error, $message = false)
|
||||
private function error($error, ?string $message = null)
|
||||
{
|
||||
// Accepts either an error object or an error code and message
|
||||
if ($message && !is_object($error)) {
|
||||
$error = new IXR_Error($error, $message);
|
||||
if (!$error instanceof Error) {
|
||||
$error = new Error($error, $message);
|
||||
}
|
||||
|
||||
$this->output($error->getXml());
|
||||
}
|
||||
|
||||
@ -140,16 +231,15 @@ class IXR_Server
|
||||
*
|
||||
* @access private
|
||||
* @param string $xml 输出xml
|
||||
* @return 输出xml
|
||||
*/
|
||||
private function output($xml)
|
||||
private function output(string $xml)
|
||||
{
|
||||
$xml = '<?xml version="1.0"?>'."\n".$xml;
|
||||
$xml = '<?xml version="1.0"?>' . "\n" . $xml;
|
||||
$length = strlen($xml);
|
||||
header('Connection: close');
|
||||
header('Content-Length: '.$length);
|
||||
header('Content-Length: ' . $length);
|
||||
header('Content-Type: text/xml');
|
||||
header('Date: '.date('r'));
|
||||
header('Date: ' . date('r'));
|
||||
echo $xml;
|
||||
exit;
|
||||
}
|
||||
@ -161,7 +251,7 @@ class IXR_Server
|
||||
* @param string $method 方法名
|
||||
* @return mixed
|
||||
*/
|
||||
private function hasMethod($method)
|
||||
private function hasMethod(string $method)
|
||||
{
|
||||
return in_array($method, array_keys($this->callbacks));
|
||||
}
|
||||
@ -175,20 +265,20 @@ class IXR_Server
|
||||
private function setCapabilities()
|
||||
{
|
||||
// Initialises capabilities array
|
||||
$this->capabilities = array(
|
||||
'xmlrpc' => array(
|
||||
'specUrl' => 'http://www.xmlrpc.com/spec',
|
||||
$this->capabilities = [
|
||||
'xmlrpc' => [
|
||||
'specUrl' => 'http://www.xmlrpc.com/spec',
|
||||
'specVersion' => 1
|
||||
),
|
||||
'faults_interop' => array(
|
||||
'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
|
||||
],
|
||||
'faults_interop' => [
|
||||
'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
|
||||
'specVersion' => 20010516
|
||||
),
|
||||
'system.multicall' => array(
|
||||
'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
|
||||
],
|
||||
'system.multicall' => [
|
||||
'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
|
||||
'specVersion' => 1
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,130 +289,50 @@ class IXR_Server
|
||||
*/
|
||||
private function setCallbacks()
|
||||
{
|
||||
$this->callbacks['system.getCapabilities'] = 'this:getCapabilities';
|
||||
$this->callbacks['system.listMethods'] = 'this:listMethods';
|
||||
$this->callbacks['system.multicall'] = 'this:multiCall';
|
||||
$this->callbacks['system.getCapabilities'] = [$this, 'getCapabilities'];
|
||||
$this->callbacks['system.listMethods'] = [$this, 'listMethods'];
|
||||
$this->callbacks['system.multicall'] = [$this, 'multiCall'];
|
||||
$this->callbacks['system.methodHelp'] = [$this, 'methodHelp'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务入口
|
||||
*
|
||||
* @access private
|
||||
* @param mixed $data 输入参数
|
||||
* @return void
|
||||
*/
|
||||
private function serve($data = false)
|
||||
private function serve()
|
||||
{
|
||||
if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
|
||||
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents("php://input");
|
||||
}
|
||||
if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
|
||||
$GLOBALS['HTTP_RAW_POST_DATA'] = trim($GLOBALS['HTTP_RAW_POST_DATA']);
|
||||
}
|
||||
$message = new Message(file_get_contents('php://input') ?: '');
|
||||
|
||||
if (!$data) {
|
||||
global $HTTP_RAW_POST_DATA;
|
||||
if (!$HTTP_RAW_POST_DATA) {
|
||||
die('XML-RPC server accepts POST requests only.');
|
||||
}
|
||||
$data = $HTTP_RAW_POST_DATA;
|
||||
}
|
||||
$this->message = new IXR_Message($data);
|
||||
if (!$this->message->parse()) {
|
||||
if (!$message->parse()) {
|
||||
$this->error(-32700, 'parse error. not well formed');
|
||||
}
|
||||
if ($this->message->messageType != 'methodCall') {
|
||||
} elseif ($message->messageType != 'methodCall') {
|
||||
$this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall');
|
||||
}
|
||||
|
||||
if (0 === strpos($this->message->methodName, 'hook.')) {
|
||||
die('THIS METHOD MUST BE CALLED INSIDE.');
|
||||
}
|
||||
|
||||
$result = $this->call($this->message->methodName, $this->message->params);
|
||||
|
||||
$result = $this->call($message->methodName, $message->params);
|
||||
// Is the result an error?
|
||||
if (is_a($result, 'IXR_Error')) {
|
||||
if ($result instanceof Error) {
|
||||
$this->error($result);
|
||||
}
|
||||
|
||||
// Encode the result
|
||||
$r = new IXR_Value($result);
|
||||
$resultxml = $r->getXml();
|
||||
$r = new Value($result);
|
||||
$resultXml = $r->getXml();
|
||||
|
||||
// Create the XML
|
||||
$xml = <<<EOD
|
||||
<methodResponse>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
$resultxml
|
||||
$resultXml
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodResponse>
|
||||
|
||||
EOD;
|
||||
// hook
|
||||
if ($this->hasMethod('hook.beforeOutput')) {
|
||||
$this->call('hook.beforeOutput', array());
|
||||
}
|
||||
|
||||
|
||||
// Send it
|
||||
$this->output($xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认参数
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $args 输入参数
|
||||
* @return array
|
||||
*/
|
||||
public function getCapabilities($args)
|
||||
{
|
||||
return $this->capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出所有方法
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $args 输入参数
|
||||
* @return mixed
|
||||
*/
|
||||
public function listMethods($args)
|
||||
{
|
||||
// Returns a list of methods - uses array_reverse to ensure user defined
|
||||
// methods are listed before server defined methods
|
||||
return array_reverse(array_keys($this->callbacks));
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次处理多个请求
|
||||
*
|
||||
* @access public
|
||||
* @param void $methodcalls
|
||||
* @return array
|
||||
*/
|
||||
public function multiCall($methodcalls)
|
||||
{
|
||||
// See http://www.xmlrpc.com/discuss/msgReader$1208
|
||||
$return = array();
|
||||
foreach ($methodcalls as $call) {
|
||||
$method = $call['methodName'];
|
||||
$params = $call['params'];
|
||||
if ($method == 'system.multicall') {
|
||||
$result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden');
|
||||
} else {
|
||||
$result = $this->call($method, $params);
|
||||
}
|
||||
if (is_a($result, 'IXR_Error')) {
|
||||
$return[] = array(
|
||||
'faultCode' => $result->code,
|
||||
'faultString' => $result->message
|
||||
);
|
||||
} else {
|
||||
$return[] = array($result);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
|
||||
Version 1.61 - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars)
|
||||
Site: http://scripts.incutio.com/xmlrpc/
|
||||
Manual: http://scripts.incutio.com/xmlrpc/manual.php
|
||||
Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php
|
||||
*/
|
||||
|
||||
namespace IXR;
|
||||
|
||||
/**
|
||||
* IXR值
|
||||
*
|
||||
* @package IXR
|
||||
*/
|
||||
class IXR_Value {
|
||||
var $data;
|
||||
var $type;
|
||||
function __construct ($data, $type = false) {
|
||||
class Value
|
||||
{
|
||||
private $data;
|
||||
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @param bool|string $type
|
||||
*/
|
||||
public function __construct($data, $type = false)
|
||||
{
|
||||
$this->data = $data;
|
||||
if (!$type) {
|
||||
$type = $this->calculateType();
|
||||
@ -24,16 +27,55 @@ class IXR_Value {
|
||||
if ($type == 'struct') {
|
||||
/* Turn all the values in the array in to new IXR_Value objects */
|
||||
foreach ($this->data as $key => $value) {
|
||||
$this->data[$key] = new IXR_Value($value);
|
||||
$this->data[$key] = new Value($value);
|
||||
}
|
||||
}
|
||||
if ($type == 'array') {
|
||||
for ($i = 0, $j = count($this->data); $i < $j; $i++) {
|
||||
$this->data[$i] = new IXR_Value($this->data[$i]);
|
||||
$this->data[$i] = new Value($this->data[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
function calculateType() {
|
||||
|
||||
public function getXml(): string
|
||||
{
|
||||
/* Return XML for this value */
|
||||
switch ($this->type) {
|
||||
case 'boolean':
|
||||
return '<boolean>' . (($this->data) ? '1' : '0') . '</boolean>';
|
||||
case 'int':
|
||||
return '<int>' . $this->data . '</int>';
|
||||
case 'double':
|
||||
return '<double>' . $this->data . '</double>';
|
||||
case 'string':
|
||||
return '<string>' . htmlspecialchars($this->data) . '</string>';
|
||||
case 'array':
|
||||
$return = '<array><data>' . "\n";
|
||||
foreach ($this->data as $item) {
|
||||
$return .= ' <value>' . $item->getXml() . "</value>\n";
|
||||
}
|
||||
$return .= '</data></array>';
|
||||
return $return;
|
||||
case 'struct':
|
||||
$return = '<struct>' . "\n";
|
||||
foreach ($this->data as $name => $value) {
|
||||
$return .= " <member><name>$name</name><value>";
|
||||
$return .= $value->getXml() . "</value></member>\n";
|
||||
}
|
||||
$return .= '</struct>';
|
||||
return $return;
|
||||
case 'date':
|
||||
case 'base64':
|
||||
return $this->data->getXml();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function calculateType(): string
|
||||
{
|
||||
if ($this->data === true || $this->data === false) {
|
||||
return 'boolean';
|
||||
}
|
||||
@ -52,7 +94,6 @@ class IXR_Value {
|
||||
}
|
||||
// If it is a normal PHP object convert it in to a struct
|
||||
if (is_object($this->data)) {
|
||||
|
||||
$this->data = get_object_vars($this->data);
|
||||
return 'struct';
|
||||
}
|
||||
@ -66,46 +107,9 @@ class IXR_Value {
|
||||
return 'array';
|
||||
}
|
||||
}
|
||||
function getXml() {
|
||||
/* Return XML for this value */
|
||||
switch ($this->type) {
|
||||
case 'boolean':
|
||||
return '<boolean>'.(($this->data) ? '1' : '0').'</boolean>';
|
||||
break;
|
||||
case 'int':
|
||||
return '<int>'.$this->data.'</int>';
|
||||
break;
|
||||
case 'double':
|
||||
return '<double>'.$this->data.'</double>';
|
||||
break;
|
||||
case 'string':
|
||||
return '<string>'.htmlspecialchars($this->data).'</string>';
|
||||
break;
|
||||
case 'array':
|
||||
$return = '<array><data>'."\n";
|
||||
foreach ($this->data as $item) {
|
||||
$return .= ' <value>'.$item->getXml()."</value>\n";
|
||||
}
|
||||
$return .= '</data></array>';
|
||||
return $return;
|
||||
break;
|
||||
case 'struct':
|
||||
$return = '<struct>'."\n";
|
||||
foreach ($this->data as $name => $value) {
|
||||
$return .= " <member><name>$name</name><value>";
|
||||
$return .= $value->getXml()."</value></member>\n";
|
||||
}
|
||||
$return .= '</struct>';
|
||||
return $return;
|
||||
break;
|
||||
case 'date':
|
||||
case 'base64':
|
||||
return $this->data->getXml();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isStruct($array) {
|
||||
|
||||
private function isStruct($array): bool
|
||||
{
|
||||
/* Nasty function to check if an array is a struct or not */
|
||||
$expected = 0;
|
||||
foreach ($array as $key => $value) {
|
||||
|
545
var/Json.php
545
var/Json.php
@ -1,545 +0,0 @@
|
||||
<?php
|
||||
/**********************************
|
||||
* Created on: 2007-2-2
|
||||
* File Name : lib.json.php
|
||||
* Copyright : 2005 Michal Migursk
|
||||
* License : http://www.opensource.org/licenses/bsd-license.php
|
||||
*********************************/
|
||||
|
||||
class Json
|
||||
{
|
||||
const SERVICES_JSON_SLICE = 1;
|
||||
const SERVICES_JSON_IN_STR = 2;
|
||||
const SERVICES_JSON_IN_ARR = 3;
|
||||
const SERVICES_JSON_IN_OBJ = 4;
|
||||
const SERVICES_JSON_IN_CMT = 5;
|
||||
const SERVICES_JSON_LOOSE_TYPE = 16;
|
||||
const SERVICES_JSON_SUPPRESS_ERRORS = 32;
|
||||
const E_JSONTYPE = 'json decode error';
|
||||
|
||||
/**
|
||||
* 对配对值编码
|
||||
*
|
||||
* @access public
|
||||
* @param string $name 名称
|
||||
* @param mixed $value 值
|
||||
* @return string
|
||||
*/
|
||||
public static function _name_value($name, $value)
|
||||
{
|
||||
$encoded_value = self::_encode($value);
|
||||
|
||||
if (self::_is_error($encoded_value)) {
|
||||
return $encoded_value;
|
||||
}
|
||||
|
||||
return self::_encode(strval($name)) . ':' . $encoded_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转换为json串
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $var 需要转换的对象
|
||||
* @return string
|
||||
*/
|
||||
public static function _encode($var)
|
||||
{
|
||||
switch (gettype($var)) {
|
||||
case 'boolean':
|
||||
return $var ? 'true' : 'false';
|
||||
|
||||
case 'NULL':
|
||||
return 'null';
|
||||
|
||||
case 'integer':
|
||||
return (int)$var;
|
||||
|
||||
case 'double':
|
||||
case 'float':
|
||||
return (float)$var;
|
||||
|
||||
case 'string':
|
||||
$ascii = '';
|
||||
$strlen_var = strlen($var);
|
||||
|
||||
for ($c = 0; $c < $strlen_var; ++ $c) {
|
||||
|
||||
$ord_var_c = ord($var[$c]);
|
||||
|
||||
switch (true) {
|
||||
case $ord_var_c == 0x08:
|
||||
$ascii .= '\b';
|
||||
break;
|
||||
case $ord_var_c == 0x09:
|
||||
$ascii .= '\t';
|
||||
break;
|
||||
case $ord_var_c == 0x0A:
|
||||
$ascii .= '\n';
|
||||
break;
|
||||
case $ord_var_c == 0x0C:
|
||||
$ascii .= '\f';
|
||||
break;
|
||||
case $ord_var_c == 0x0D:
|
||||
$ascii .= '\r';
|
||||
break;
|
||||
|
||||
case $ord_var_c == 0x22:
|
||||
case $ord_var_c == 0x2F:
|
||||
case $ord_var_c == 0x5C:
|
||||
$ascii .= '\\' . $var[$c];
|
||||
break;
|
||||
|
||||
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
||||
$ascii .= $var[$c];
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xE0) == 0xC0):
|
||||
$char = pack('C*', $ord_var_c, ord($var[$c + 1]));
|
||||
$c += 1;
|
||||
$utf16 = self::utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF0) == 0xE0):
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var[$c + 1]),
|
||||
ord($var[$c + 2]));
|
||||
$c += 2;
|
||||
$utf16 = self::utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF8) == 0xF0):
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var[$c + 1]),
|
||||
ord($var[$c + 2]),
|
||||
ord($var[$c + 3]));
|
||||
$c += 3;
|
||||
$utf16 = self::utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFC) == 0xF8):
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var[$c + 1]),
|
||||
ord($var[$c + 2]),
|
||||
ord($var[$c + 3]),
|
||||
ord($var[$c + 4]));
|
||||
$c += 4;
|
||||
$utf16 = self::utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFE) == 0xFC):
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var[$c + 1]),
|
||||
ord($var[$c + 2]),
|
||||
ord($var[$c + 3]),
|
||||
ord($var[$c + 4]),
|
||||
ord($var[$c + 5]));
|
||||
$c += 5;
|
||||
$utf16 = self::utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '"' . $ascii . '"';
|
||||
|
||||
case 'array':
|
||||
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
||||
$properties = array_map(['Json', '_name_value'],
|
||||
array_keys($var),
|
||||
array_values($var));
|
||||
|
||||
foreach ($properties as $property) {
|
||||
if (self::_is_error($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
}
|
||||
|
||||
// treat it like a regular array
|
||||
$elements = array_map(['Json', '_encode'], $var);
|
||||
|
||||
foreach ($elements as $element) {
|
||||
if (self::_is_error($element)) {
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
return '[' . join(',', $elements) . ']';
|
||||
|
||||
case 'object':
|
||||
$vars = get_object_vars($var);
|
||||
|
||||
$properties = array_map(['Json', '_name_value'],
|
||||
array_keys($vars),
|
||||
array_values($vars));
|
||||
|
||||
foreach ($properties as $property) {
|
||||
if (self::_is_error($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将utf8转换为utf16
|
||||
*
|
||||
* @access private
|
||||
* @param string $utf8 utf8字符串
|
||||
* @return string
|
||||
*/
|
||||
private static function utf82utf16($utf8)
|
||||
{
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
||||
}
|
||||
|
||||
switch (strlen($utf8)) {
|
||||
case 1:
|
||||
return $utf8;
|
||||
|
||||
case 2:
|
||||
return chr(0x07 & (ord($utf8[0]) >> 2))
|
||||
. chr((0xC0 & (ord($utf8[0]) << 6))
|
||||
| (0x3F & ord($utf8[1])));
|
||||
case 3:
|
||||
return chr((0xF0 & (ord($utf8[0]) << 4))
|
||||
| (0x0F & (ord($utf8[1]) >> 2)))
|
||||
. chr((0xC0 & (ord($utf8[1]) << 6))
|
||||
| (0x7F & ord($utf8[2])));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断错误
|
||||
*
|
||||
* @access private
|
||||
* @param mixed $data 错误对象
|
||||
* @param string $code 错误代码
|
||||
* @return boolean
|
||||
*/
|
||||
private static function _is_error($data, $code = null)
|
||||
{
|
||||
if (is_object($data) && (get_class($data) == 'services_json_error' ||
|
||||
is_subclass_of($data, 'services_json_error'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对变量进行json编码
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $var 需要处理的对象
|
||||
* @return string
|
||||
*/
|
||||
public static function encode($var)
|
||||
{
|
||||
if (function_exists('json_encode')) {
|
||||
/** from php 5.1 */
|
||||
return json_encode($var);
|
||||
} else {
|
||||
return self::_encode($var);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串进行json解码
|
||||
*
|
||||
* @access public
|
||||
* @param string $var 需要解码的字符串
|
||||
* @param boolean $assoc 是否强制解释为数组
|
||||
* @return mixed
|
||||
*/
|
||||
public static function decode($var, $assoc = false)
|
||||
{
|
||||
if (function_exists('json_decode')) {
|
||||
/** from php 5.1 */
|
||||
return json_decode($var, $assoc);
|
||||
} else {
|
||||
$result = self::_decode($var);
|
||||
}
|
||||
|
||||
if ($assoc && is_object($result)) {
|
||||
return (array)$result;
|
||||
} elseif (!$assoc && is_array($result)) {
|
||||
return (object)$result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码json字符串
|
||||
*
|
||||
* @access public
|
||||
* @param string $str 解码字符串
|
||||
* @return mixed
|
||||
*/
|
||||
public static function _decode($str)
|
||||
{
|
||||
$str = self::_reduce_string($str);
|
||||
|
||||
switch (strtolower($str)) {
|
||||
case 'true':
|
||||
return true;
|
||||
|
||||
case 'false':
|
||||
return false;
|
||||
|
||||
case 'null':
|
||||
return null;
|
||||
|
||||
default:
|
||||
$m = [];
|
||||
|
||||
if (is_numeric($str)) {
|
||||
return ((float)$str == (integer)$str)
|
||||
? (integer)$str
|
||||
: (float)$str;
|
||||
|
||||
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
||||
$delim = substr($str, 0, 1);
|
||||
$chrs = substr($str, 1, - 1);
|
||||
$utf8 = '';
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c < $strlen_chrs; ++ $c) {
|
||||
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
$ord_chrs_c = ord($chrs[$c]);
|
||||
|
||||
switch (true) {
|
||||
case $substr_chrs_c_2 == '\b':
|
||||
$utf8 .= chr(0x08);
|
||||
++ $c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\t':
|
||||
$utf8 .= chr(0x09);
|
||||
++ $c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\n':
|
||||
$utf8 .= chr(0x0A);
|
||||
++ $c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\f':
|
||||
$utf8 .= chr(0x0C);
|
||||
++ $c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\r':
|
||||
$utf8 .= chr(0x0D);
|
||||
++ $c;
|
||||
break;
|
||||
|
||||
case $substr_chrs_c_2 == '\\"':
|
||||
case $substr_chrs_c_2 == '\\\'':
|
||||
case $substr_chrs_c_2 == '\\\\':
|
||||
case $substr_chrs_c_2 == '\\/':
|
||||
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
|
||||
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
|
||||
$utf8 .= $chrs[++ $c];
|
||||
}
|
||||
break;
|
||||
|
||||
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
|
||||
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
|
||||
. chr(hexdec(substr($chrs, ($c + 4), 2)));
|
||||
$utf8 .= self::utf162utf8($utf16);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
|
||||
$utf8 .= $chrs[$c];
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xE0) == 0xC0:
|
||||
$utf8 .= substr($chrs, $c, 2);
|
||||
++ $c;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF0) == 0xE0:
|
||||
$utf8 .= substr($chrs, $c, 3);
|
||||
$c += 2;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF8) == 0xF0:
|
||||
$utf8 .= substr($chrs, $c, 4);
|
||||
$c += 3;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFC) == 0xF8:
|
||||
$utf8 .= substr($chrs, $c, 5);
|
||||
$c += 4;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFE) == 0xFC:
|
||||
$utf8 .= substr($chrs, $c, 6);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $utf8;
|
||||
|
||||
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
|
||||
if ($str [0] == '[') {
|
||||
$stk = [self::SERVICES_JSON_IN_ARR];
|
||||
$arr = [];
|
||||
} else {
|
||||
$stk = [self::SERVICES_JSON_IN_OBJ];
|
||||
$obj = new stdClass();
|
||||
}
|
||||
|
||||
array_push($stk, ['what' => self::SERVICES_JSON_SLICE,
|
||||
'where' => 0,
|
||||
'delim' => false]);
|
||||
|
||||
$chrs = substr($str, 1, - 1);
|
||||
$chrs = self::_reduce_string($chrs);
|
||||
|
||||
if ($chrs == '') {
|
||||
if (reset($stk) == self::SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} else {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$strlen_chrs = strlen($chrs);
|
||||
for ($c = 0; $c <= $strlen_chrs; ++ $c) {
|
||||
|
||||
$top = end($stk);
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
|
||||
if (($c == $strlen_chrs) || (($chrs [$c] == ',') && ($top['what'] == self::SERVICES_JSON_SLICE))) {
|
||||
$slice = substr($chrs, $top['where'], ($c - $top['where']));
|
||||
array_push($stk, ['what' => self::SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false]);
|
||||
|
||||
if (reset($stk) == self::SERVICES_JSON_IN_ARR) {
|
||||
array_push($arr, self::_decode($slice));
|
||||
|
||||
} elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) {
|
||||
$parts = [];
|
||||
|
||||
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
$key = self::_decode($parts[1]);
|
||||
$val = self::_decode($parts[2]);
|
||||
$obj->$key = $val;
|
||||
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
$key = $parts[1];
|
||||
$val = self::_decode($parts[2]);
|
||||
$obj->$key = $val;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} elseif ((($chrs [$c] == '"') || ($chrs[$c] == "'")) && ($top['what'] != self::SERVICES_JSON_IN_STR)) {
|
||||
array_push($stk, ['what' => self::SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs[$c]]);
|
||||
|
||||
} elseif (($chrs [$c] == $top['delim']) &&
|
||||
($top['what'] == self::SERVICES_JSON_IN_STR) &&
|
||||
((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
|
||||
array_pop($stk);
|
||||
|
||||
} elseif (($chrs [$c] == '[') &&
|
||||
in_array($top['what'], [self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ])) {
|
||||
array_push($stk, ['what' => self::SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false]);
|
||||
} elseif (($chrs [$c] == ']') && ($top['what'] == self::SERVICES_JSON_IN_ARR)) {
|
||||
array_pop($stk);
|
||||
} elseif (($chrs [$c] == '{') &&
|
||||
in_array($top['what'], [self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ])) {
|
||||
array_push($stk, ['what' => self::SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false]);
|
||||
} elseif (($chrs [$c] == '}') && ($top['what'] == self::SERVICES_JSON_IN_OBJ)) {
|
||||
array_pop($stk);
|
||||
} elseif (($substr_chrs_c_2 == '/*') &&
|
||||
in_array($top['what'], [self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ])) {
|
||||
array_push($stk, ['what' => self::SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false]);
|
||||
$c ++;
|
||||
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::SERVICES_JSON_IN_CMT)) {
|
||||
array_pop($stk);
|
||||
$c ++;
|
||||
for ($i = $top['where']; $i <= $c; ++ $i)
|
||||
$chrs = substr_replace($chrs, ' ', $i, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (reset($stk) == self::SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除特殊格式
|
||||
*
|
||||
* @access private
|
||||
* @param string $str 待处理字符串
|
||||
* @return string
|
||||
*/
|
||||
private static function _reduce_string($str)
|
||||
{
|
||||
$str = preg_replace([
|
||||
'#^\s*//(.+)$#m',
|
||||
'#^\s*/\*(.+)\*/#Us',
|
||||
'#/\*(.+)\*/\s*$#Us'
|
||||
], '', $str);
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将utf16转换为utf8
|
||||
*
|
||||
* @access private
|
||||
* @param string $utf16 utf16字符串
|
||||
* @return string
|
||||
*/
|
||||
private static function utf162utf8($utf16)
|
||||
{
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
||||
}
|
||||
$bytes = (ord($utf16[0]) << 8) | ord($utf16[1]);
|
||||
|
||||
switch (true) {
|
||||
case ((0x7F & $bytes) == $bytes):
|
||||
return chr(0x7F & $bytes);
|
||||
|
||||
case (0x07FF & $bytes) == $bytes:
|
||||
return chr(0xC0 | (($bytes >> 6) & 0x1F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
|
||||
case (0xFFFF & $bytes) == $bytes:
|
||||
return chr(0xE0 | (($bytes >> 12) & 0x0F))
|
||||
. chr(0x80 | (($bytes >> 6) & 0x3F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
@ -1,65 +0,0 @@
|
||||
<?php
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
|
||||
/**
|
||||
* Markdown解析
|
||||
*
|
||||
* @package Markdown
|
||||
* @copyright Copyright (c) 2014 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
*/
|
||||
class Markdown
|
||||
{
|
||||
/**
|
||||
* convert
|
||||
*
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public static function convert($text)
|
||||
{
|
||||
static $parser;
|
||||
|
||||
if (empty($parser)) {
|
||||
$parser = new HyperDown();
|
||||
|
||||
$parser->hook('afterParseCode', function ($html) {
|
||||
return preg_replace("/<code class=\"([_a-z0-9-]+)\">/i", "<code class=\"lang-\\1\">", $html);
|
||||
});
|
||||
|
||||
$parser->enableHtml(true);
|
||||
}
|
||||
|
||||
return str_replace('<p><!--more--></p>', '<!--more-->', $parser->makeHtml($text));
|
||||
}
|
||||
|
||||
/**
|
||||
* transerCodeClass
|
||||
*
|
||||
* @param string $html
|
||||
* @return string
|
||||
*/
|
||||
public static function transerCodeClass($html)
|
||||
{
|
||||
return preg_replace("/<code class=\"([_a-z0-9-]+)\">/i", "<code class=\"lang-\\1\">", $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $html
|
||||
* @return mixed
|
||||
*/
|
||||
public static function transerComment($html)
|
||||
{
|
||||
return preg_replace_callback("/<!\-\-(.+?)\-\->/s", ['Markdown', 'transerCommentCallback'], $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $matches
|
||||
* @return string
|
||||
*/
|
||||
public static function transerCommentCallback($matches)
|
||||
{
|
||||
return self::$parser->makeHolder($matches[0]);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* 配置管理
|
||||
*
|
||||
* @category typecho
|
||||
* @package Config
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
namespace Typecho;
|
||||
|
||||
/**
|
||||
* 配置管理类
|
||||
@ -17,7 +10,7 @@
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
*/
|
||||
class Typecho_Config implements Iterator
|
||||
class Config implements \Iterator, \ArrayAccess
|
||||
{
|
||||
/**
|
||||
* 当前配置
|
||||
@ -25,13 +18,13 @@ class Typecho_Config implements Iterator
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $_currentConfig = [];
|
||||
private $currentConfig = [];
|
||||
|
||||
/**
|
||||
* 实例化一个当前配置
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $config 配置列表
|
||||
* @param array|string|null $config 配置列表
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
@ -44,13 +37,13 @@ class Typecho_Config implements Iterator
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array|string $config 配置列表
|
||||
* @param array|string|null $config 配置列表
|
||||
*
|
||||
* @return Typecho_Config
|
||||
* @return Config
|
||||
*/
|
||||
public static function factory($config = []): Typecho_Config
|
||||
public static function factory($config = []): Config
|
||||
{
|
||||
return new Typecho_Config($config);
|
||||
return new self($config);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +61,7 @@ class Typecho_Config implements Iterator
|
||||
if (empty($config)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** 初始化参数 */
|
||||
if (is_string($config)) {
|
||||
parse_str($config, $params);
|
||||
@ -78,12 +71,20 @@ class Typecho_Config implements Iterator
|
||||
|
||||
/** 设置默认参数 */
|
||||
foreach ($params as $name => $value) {
|
||||
if ($replace || !array_key_exists($name, $this->_currentConfig)) {
|
||||
$this->_currentConfig[$name] = $value;
|
||||
if ($replace || !array_key_exists($name, $this->currentConfig)) {
|
||||
$this->currentConfig[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->currentConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重设指针
|
||||
*
|
||||
@ -92,7 +93,7 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
reset($this->_currentConfig);
|
||||
reset($this->currentConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,7 +104,7 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->_currentConfig);
|
||||
return current($this->currentConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,7 +115,7 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
next($this->_currentConfig);
|
||||
next($this->currentConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,7 +126,7 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return key($this->_currentConfig);
|
||||
return key($this->currentConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,7 +149,7 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function __get(string $name)
|
||||
{
|
||||
return $this->_currentConfig[$name] ?? null;
|
||||
return $this->offsetGet($name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -161,7 +162,7 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function __set(string $name, $value)
|
||||
{
|
||||
$this->_currentConfig[$name] = $value;
|
||||
$this->offsetSet($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,7 +175,7 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function __call(string $name, ?array $args)
|
||||
{
|
||||
echo $this->_currentConfig[$name];
|
||||
echo $this->currentConfig[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +187,7 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function __isSet(string $name): bool
|
||||
{
|
||||
return isset($this->_currentConfig[$name]);
|
||||
return $this->offsetExists($name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,7 +198,7 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return serialize($this->_currentConfig);
|
||||
return serialize($this->currentConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,6 +206,41 @@ class Typecho_Config implements Iterator
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->_currentConfig;
|
||||
return $this->currentConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
return isset($this->currentConfig[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->currentConfig[$offset] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->currentConfig[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->currentConfig[$offset]);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* cookie支持
|
||||
*
|
||||
* @category typecho
|
||||
* @package Cookie
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
namespace Typecho;
|
||||
|
||||
/**
|
||||
* cookie支持
|
||||
@ -16,7 +9,7 @@
|
||||
* @category typecho
|
||||
* @package Cookie
|
||||
*/
|
||||
class Typecho_Cookie
|
||||
class Cookie
|
||||
{
|
||||
/**
|
||||
* 前缀
|
||||
@ -24,7 +17,7 @@ class Typecho_Cookie
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
private static $_prefix = '';
|
||||
private static $prefix = '';
|
||||
|
||||
/**
|
||||
* 路径
|
||||
@ -32,7 +25,7 @@ class Typecho_Cookie
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
private static $_path = '/';
|
||||
private static $path = '/';
|
||||
|
||||
/**
|
||||
* 获取前缀
|
||||
@ -42,7 +35,7 @@ class Typecho_Cookie
|
||||
*/
|
||||
public static function getPrefix(): string
|
||||
{
|
||||
return self::$_prefix;
|
||||
return self::$prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,11 +48,11 @@ class Typecho_Cookie
|
||||
*/
|
||||
public static function setPrefix(string $url)
|
||||
{
|
||||
self::$_prefix = md5($url);
|
||||
self::$prefix = md5($url);
|
||||
$parsed = parse_url($url);
|
||||
|
||||
/** 在路径后面强制加上斜杠 */
|
||||
self::$_path = empty($parsed['path']) ? '/' : Typecho_Common::url(null, $parsed['path']);
|
||||
self::$path = empty($parsed['path']) ? '/' : Common::url(null, $parsed['path']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,22 +63,19 @@ class Typecho_Cookie
|
||||
*/
|
||||
public static function getPath(): string
|
||||
{
|
||||
return self::$_path;
|
||||
return self::$path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定的COOKIE值
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $key 指定的参数
|
||||
* @param string|null $default 默认的参数
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get(string $key, ?string $default = null)
|
||||
{
|
||||
$key = self::$_prefix . $key;
|
||||
$key = self::$prefix . $key;
|
||||
$value = $_COOKIE[$key] ?? $default;
|
||||
return is_array($value) ? $default : $value;
|
||||
}
|
||||
@ -93,38 +83,30 @@ class Typecho_Cookie
|
||||
/**
|
||||
* 设置指定的COOKIE值
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $key 指定的参数
|
||||
* @param mixed $value 设置的值
|
||||
* @param integer $expire 过期时间,默认为0,表示随会话时间结束
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function set(string $key, $value, int $expire = 0)
|
||||
{
|
||||
$key = self::$_prefix . $key;
|
||||
setrawcookie($key, rawurlencode($value), $expire, self::$_path);
|
||||
$key = self::$prefix . $key;
|
||||
$_COOKIE[$key] = $value;
|
||||
Response::getInstance()->setCookie($key, $value, $expire, self::$path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定的COOKIE值
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $key 指定的参数
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function delete(string $key)
|
||||
{
|
||||
$key = self::$_prefix . $key;
|
||||
$key = self::$prefix . $key;
|
||||
if (!isset($_COOKIE[$key])) {
|
||||
return;
|
||||
}
|
||||
|
||||
setcookie($key, '', time() - 2592000, self::$_path);
|
||||
Response::getInstance()->setCookie($key, '', -1, self::$path);
|
||||
unset($_COOKIE[$key]);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Typecho;
|
||||
|
||||
/**
|
||||
* 日期处理
|
||||
*
|
||||
@ -7,7 +9,7 @@
|
||||
* @category typecho
|
||||
* @package Date
|
||||
*/
|
||||
class Typecho_Date
|
||||
class Date
|
||||
{
|
||||
/**
|
||||
* 期望时区偏移
|
||||
@ -41,26 +43,40 @@ class Typecho_Date
|
||||
*/
|
||||
public $timeStamp = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $year;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $month;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $day;
|
||||
|
||||
/**
|
||||
* 初始化参数
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param integer|null $time 时间戳
|
||||
*/
|
||||
public function __construct(?int $time = NULL)
|
||||
public function __construct(?int $time = null)
|
||||
{
|
||||
$this->timeStamp = (NULL === $time ? self::time() : $time) + (self::$timezoneOffset - self::$serverTimezoneOffset);
|
||||
$this->timeStamp = (null === $time ? self::time() : $time)
|
||||
+ (self::$timezoneOffset - self::$serverTimezoneOffset);
|
||||
|
||||
$this->year = date('Y', $this->timeStamp);
|
||||
$this->month = date('m', $this->timeStamp);
|
||||
$this->day = date('d', $this->timeStamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前期望的时区偏移
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param integer $offset
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setTimezoneOffset(int $offset)
|
||||
{
|
||||
@ -71,10 +87,7 @@ class Typecho_Date
|
||||
/**
|
||||
* 获取格式化时间
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $format 时间格式
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(string $format): string
|
||||
@ -85,35 +98,11 @@ class Typecho_Date
|
||||
/**
|
||||
* 获取国际化偏移时间
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function word(): string
|
||||
{
|
||||
return Typecho_I18n::dateWord($this->timeStamp, self::time() + (self::$timezoneOffset - self::$serverTimezoneOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单项数据
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $name 名称
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function __get(string $name)
|
||||
{
|
||||
switch ($name) {
|
||||
case 'year':
|
||||
return date('Y', $this->timeStamp);
|
||||
case 'month':
|
||||
return date('m', $this->timeStamp);
|
||||
case 'day':
|
||||
return date('d', $this->timeStamp);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return I18n::dateWord($this->timeStamp, self::time() + (self::$timezoneOffset - self::$serverTimezoneOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,11 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
* Typecho Blog Platform
|
||||
*
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id: Db.php 107 2008-04-11 07:14:43Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho;
|
||||
|
||||
use Typecho\Db\Adapter;
|
||||
use Typecho\Db\Query;
|
||||
use Typecho\Db\Exception as DbException;
|
||||
|
||||
/**
|
||||
* 包含获取数据支持方法的类.
|
||||
@ -14,56 +13,56 @@
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db
|
||||
class Db
|
||||
{
|
||||
/** 读取数据库 */
|
||||
const READ = 1;
|
||||
public const READ = 1;
|
||||
|
||||
/** 写入数据库 */
|
||||
const WRITE = 2;
|
||||
public const WRITE = 2;
|
||||
|
||||
/** 升序方式 */
|
||||
const SORT_ASC = 'ASC';
|
||||
public const SORT_ASC = 'ASC';
|
||||
|
||||
/** 降序方式 */
|
||||
const SORT_DESC = 'DESC';
|
||||
public const SORT_DESC = 'DESC';
|
||||
|
||||
/** 表内连接方式 */
|
||||
const INNER_JOIN = 'INNER';
|
||||
public const INNER_JOIN = 'INNER';
|
||||
|
||||
/** 表外连接方式 */
|
||||
const OUTER_JOIN = 'OUTER';
|
||||
public const OUTER_JOIN = 'OUTER';
|
||||
|
||||
/** 表左连接方式 */
|
||||
const LEFT_JOIN = 'LEFT';
|
||||
public const LEFT_JOIN = 'LEFT';
|
||||
|
||||
/** 表右连接方式 */
|
||||
const RIGHT_JOIN = 'RIGHT';
|
||||
public const RIGHT_JOIN = 'RIGHT';
|
||||
|
||||
/** 数据库查询操作 */
|
||||
const SELECT = 'SELECT';
|
||||
public const SELECT = 'SELECT';
|
||||
|
||||
/** 数据库更新操作 */
|
||||
const UPDATE = 'UPDATE';
|
||||
public const UPDATE = 'UPDATE';
|
||||
|
||||
/** 数据库插入操作 */
|
||||
const INSERT = 'INSERT';
|
||||
public const INSERT = 'INSERT';
|
||||
|
||||
/** 数据库删除操作 */
|
||||
const DELETE = 'DELETE';
|
||||
public const DELETE = 'DELETE';
|
||||
|
||||
/**
|
||||
* 数据库适配器
|
||||
* @var Typecho_Db_Adapter
|
||||
* @var Adapter
|
||||
*/
|
||||
private $_adapter;
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
* 默认配置
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_config;
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* 已经连接
|
||||
@ -71,7 +70,7 @@ class Typecho_Db
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $_connectedPool;
|
||||
private $connectedPool;
|
||||
|
||||
/**
|
||||
* 前缀
|
||||
@ -79,7 +78,7 @@ class Typecho_Db
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_prefix;
|
||||
private $prefix;
|
||||
|
||||
/**
|
||||
* 适配器名称
|
||||
@ -87,13 +86,13 @@ class Typecho_Db
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_adapterName;
|
||||
private $adapterName;
|
||||
|
||||
/**
|
||||
* 实例化的数据库对象
|
||||
* @var Typecho_Db
|
||||
* @var Db
|
||||
*/
|
||||
private static $_instance;
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* 数据库类构造函数
|
||||
@ -101,32 +100,33 @@ class Typecho_Db
|
||||
* @param mixed $adapterName 适配器名称
|
||||
* @param string $prefix 前缀
|
||||
*
|
||||
* @throws Typecho_Db_Exception
|
||||
* @throws DbException
|
||||
*/
|
||||
public function __construct($adapterName, string $prefix = 'typecho_')
|
||||
{
|
||||
/** 获取适配器名称 */
|
||||
$this->_adapterName = $adapterName;
|
||||
$adapterName = $adapterName == 'Mysql' ? 'Mysqli' : $adapterName;
|
||||
$this->adapterName = $adapterName;
|
||||
|
||||
/** 数据库适配器 */
|
||||
$adapterName = 'Typecho_Db_Adapter_' . $adapterName;
|
||||
$adapterName = '\Typecho\Db\Adapter\\' . str_replace('_', '\\', $adapterName);
|
||||
|
||||
if (!call_user_func([$adapterName, 'isAvailable'])) {
|
||||
throw new Typecho_Db_Exception("Adapter {$adapterName} is not available");
|
||||
throw new DbException("Adapter {$adapterName} is not available");
|
||||
}
|
||||
|
||||
$this->_prefix = $prefix;
|
||||
$this->prefix = $prefix;
|
||||
|
||||
/** 初始化内部变量 */
|
||||
$this->_connectedPool = [];
|
||||
$this->connectedPool = [];
|
||||
|
||||
$this->_config = [
|
||||
$this->config = [
|
||||
self::READ => [],
|
||||
self::WRITE => []
|
||||
];
|
||||
|
||||
//实例化适配器对象
|
||||
$this->_adapter = new $adapterName();
|
||||
$this->adapter = new $adapterName();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,7 +137,7 @@ class Typecho_Db
|
||||
*/
|
||||
public function getAdapterName(): string
|
||||
{
|
||||
return $this->_adapterName;
|
||||
return $this->adapterName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,21 +148,21 @@ class Typecho_Db
|
||||
*/
|
||||
public function getPrefix(): string
|
||||
{
|
||||
return $this->_prefix;
|
||||
return $this->prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Typecho_Config $config
|
||||
* @param Config $config
|
||||
* @param int $op
|
||||
*/
|
||||
public function addConfig(Typecho_Config $config, int $op)
|
||||
public function addConfig(Config $config, int $op)
|
||||
{
|
||||
if ($op & self::READ) {
|
||||
$this->_config[self::READ][] = $config;
|
||||
$this->config[self::READ][] = $config;
|
||||
}
|
||||
|
||||
if ($op & self::WRITE) {
|
||||
$this->_config[self::WRITE][] = $config;
|
||||
$this->config[self::WRITE][] = $config;
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,18 +171,18 @@ class Typecho_Db
|
||||
*
|
||||
* @param int $op
|
||||
*
|
||||
* @return Typecho_Config
|
||||
* @throws Typecho_Db_Exception
|
||||
* @return Config
|
||||
* @throws DbException
|
||||
*/
|
||||
public function getConfig(int $op): Typecho_Config
|
||||
public function getConfig(int $op): Config
|
||||
{
|
||||
if (empty($this->_config[$op])) {
|
||||
/** Typecho_Db_Exception */
|
||||
throw new Typecho_Db_Exception('Missing Database Connection');
|
||||
if (empty($this->config[$op])) {
|
||||
/** DbException */
|
||||
throw new DbException('Missing Database Connection');
|
||||
}
|
||||
|
||||
$key = array_rand($this->_config[$op]);
|
||||
return $this->_config[$op][$key];
|
||||
$key = array_rand($this->config[$op]);
|
||||
return $this->config[$op][$key];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -192,7 +192,7 @@ class Typecho_Db
|
||||
*/
|
||||
public function flushPool()
|
||||
{
|
||||
$this->_connectedPool = [];
|
||||
$this->connectedPool = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -201,27 +201,27 @@ class Typecho_Db
|
||||
* @param int $op
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Typecho_Db_Exception
|
||||
* @throws DbException
|
||||
*/
|
||||
public function selectDb(int $op)
|
||||
{
|
||||
if (!isset($this->_connectedPool[$op])) {
|
||||
if (!isset($this->connectedPool[$op])) {
|
||||
$selectConnectionConfig = $this->getConfig($op);
|
||||
$selectConnectionHandle = $this->_adapter->connect($selectConnectionConfig);
|
||||
$this->_connectedPool[$op] = $selectConnectionHandle;
|
||||
$selectConnectionHandle = $this->adapter->connect($selectConnectionConfig);
|
||||
$this->connectedPool[$op] = $selectConnectionHandle;
|
||||
}
|
||||
|
||||
return $this->_connectedPool[$op];
|
||||
return $this->connectedPool[$op];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取SQL词法构建器实例化对象
|
||||
*
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function sql(): Typecho_Db_Query
|
||||
public function sql(): Query
|
||||
{
|
||||
return new Typecho_Db_Query($this->_adapter, $this->_prefix);
|
||||
return new Query($this->adapter, $this->prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -234,7 +234,7 @@ class Typecho_Db
|
||||
*/
|
||||
public function addServer(array $config, int $op)
|
||||
{
|
||||
$this->addConfig(Typecho_Config::factory($config), $op);
|
||||
$this->addConfig(Config::factory($config), $op);
|
||||
$this->flushPool();
|
||||
}
|
||||
|
||||
@ -244,40 +244,40 @@ class Typecho_Db
|
||||
* @param int $op
|
||||
*
|
||||
* @return string
|
||||
* @throws Typecho_Db_Exception
|
||||
* @throws DbException
|
||||
*/
|
||||
public function getVersion(int $op = self::READ): string
|
||||
{
|
||||
return $this->_adapter->getVersion($this->selectDb($op));
|
||||
return $this->adapter->getVersion($this->selectDb($op));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认数据库对象
|
||||
*
|
||||
* @access public
|
||||
* @param Typecho_Db $db 数据库对象
|
||||
* @param Db $db 数据库对象
|
||||
* @return void
|
||||
*/
|
||||
public static function set(Typecho_Db $db)
|
||||
public static function set(Db $db)
|
||||
{
|
||||
self::$_instance = $db;
|
||||
self::$instance = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库实例化对象
|
||||
* 用静态变量存储实例化的数据库对象,可以保证数据连接仅进行一次
|
||||
*
|
||||
* @return Typecho_Db
|
||||
* @throws Typecho_Db_Exception
|
||||
* @return Db
|
||||
* @throws DbException
|
||||
*/
|
||||
public static function get(): Typecho_Db
|
||||
public static function get(): Db
|
||||
{
|
||||
if (empty(self::$_instance)) {
|
||||
/** Typecho_Db_Exception */
|
||||
throw new Typecho_Db_Exception('Missing Database Object');
|
||||
if (empty(self::$instance)) {
|
||||
/** DbException */
|
||||
throw new DbException('Missing Database Object');
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -285,10 +285,10 @@ class Typecho_Db
|
||||
*
|
||||
* @param ...$ags
|
||||
*
|
||||
* @return Typecho_Db_Query
|
||||
* @throws Typecho_Db_Exception
|
||||
* @return Query
|
||||
* @throws DbException
|
||||
*/
|
||||
public function select(...$ags): Typecho_Db_Query
|
||||
public function select(...$ags): Query
|
||||
{
|
||||
$this->selectDb(self::READ);
|
||||
|
||||
@ -301,10 +301,10 @@ class Typecho_Db
|
||||
*
|
||||
* @param string $table 需要更新记录的表
|
||||
*
|
||||
* @return Typecho_Db_Query
|
||||
* @throws Typecho_Db_Exception
|
||||
* @return Query
|
||||
* @throws DbException
|
||||
*/
|
||||
public function update(string $table): Typecho_Db_Query
|
||||
public function update(string $table): Query
|
||||
{
|
||||
$this->selectDb(self::WRITE);
|
||||
|
||||
@ -316,10 +316,10 @@ class Typecho_Db
|
||||
*
|
||||
* @param string $table 需要删除记录的表
|
||||
*
|
||||
* @return Typecho_Db_Query
|
||||
* @throws Typecho_Db_Exception
|
||||
* @return Query
|
||||
* @throws DbException
|
||||
*/
|
||||
public function delete(string $table): Typecho_Db_Query
|
||||
public function delete(string $table): Query
|
||||
{
|
||||
$this->selectDb(self::WRITE);
|
||||
|
||||
@ -331,10 +331,10 @@ class Typecho_Db
|
||||
*
|
||||
* @param string $table 需要插入记录的表
|
||||
*
|
||||
* @return Typecho_Db_Query
|
||||
* @throws Typecho_Db_Exception
|
||||
* @return Query
|
||||
* @throws DbException
|
||||
*/
|
||||
public function insert(string $table): Typecho_Db_Query
|
||||
public function insert(string $table): Query
|
||||
{
|
||||
$this->selectDb(self::WRITE);
|
||||
|
||||
@ -343,12 +343,12 @@ class Typecho_Db
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @throws Typecho_Db_Exception
|
||||
* @throws DbException
|
||||
*/
|
||||
public function truncate($table)
|
||||
{
|
||||
$table = preg_replace("/^table\./", $this->_prefix, $table);
|
||||
$this->_adapter->truncate($table, $this->selectDb(self::WRITE));
|
||||
$table = preg_replace("/^table\./", $this->prefix, $table);
|
||||
$this->adapter->truncate($table, $this->selectDb(self::WRITE));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,19 +359,19 @@ class Typecho_Db
|
||||
* @param string $action 操作动作
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Typecho_Db_Exception
|
||||
* @throws DbException
|
||||
*/
|
||||
public function query($query, int $op = self::READ, string $action = self::SELECT)
|
||||
{
|
||||
$table = null;
|
||||
|
||||
/** 在适配器中执行查询 */
|
||||
if ($query instanceof Typecho_Db_Query) {
|
||||
if ($query instanceof Query) {
|
||||
$action = $query->getAttribute('action');
|
||||
$table = $query->getAttribute('table');
|
||||
$op = (self::UPDATE == $action || self::DELETE == $action
|
||||
|| self::INSERT == $action) ? self::WRITE : self::READ;
|
||||
} else if (!is_string($query)) {
|
||||
} elseif (!is_string($query)) {
|
||||
/** 如果query不是对象也不是字符串,那么将其判断为查询资源句柄,直接返回 */
|
||||
return $query;
|
||||
}
|
||||
@ -380,7 +380,7 @@ class Typecho_Db
|
||||
$handle = $this->selectDb($op);
|
||||
|
||||
/** 提交查询 */
|
||||
$resource = $this->_adapter->query($query instanceof Typecho_Db_Query ?
|
||||
$resource = $this->adapter->query($query instanceof Query ?
|
||||
$query->prepare($query) : $query, $handle, $op, $action, $table);
|
||||
|
||||
if ($action) {
|
||||
@ -388,9 +388,9 @@ class Typecho_Db
|
||||
switch ($action) {
|
||||
case self::UPDATE:
|
||||
case self::DELETE:
|
||||
return $this->_adapter->affectedRows($resource, $handle);
|
||||
return $this->adapter->affectedRows($resource, $handle);
|
||||
case self::INSERT:
|
||||
return $this->_adapter->lastInsertId($resource, $handle);
|
||||
return $this->adapter->lastInsertId($resource, $handle);
|
||||
case self::SELECT:
|
||||
default:
|
||||
return $resource;
|
||||
@ -405,52 +405,35 @@ class Typecho_Db
|
||||
* 一次取出所有行
|
||||
*
|
||||
* @param mixed $query 查询对象
|
||||
* @param array|null $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中
|
||||
* @param callable|null $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中
|
||||
*
|
||||
* @return array
|
||||
* @throws Typecho_Db_Exception
|
||||
* @throws DbException
|
||||
*/
|
||||
public function fetchAll($query, ?array $filter = null): array
|
||||
public function fetchAll($query, ?callable $filter = null): array
|
||||
{
|
||||
//执行查询
|
||||
$resource = $this->query($query, self::READ);
|
||||
$result = [];
|
||||
$resource = $this->query($query);
|
||||
$result = $this->adapter->fetchAll($resource);
|
||||
|
||||
/** 取出过滤器 */
|
||||
if (!empty($filter)) {
|
||||
[$object, $method] = $filter;
|
||||
}
|
||||
|
||||
//取出每一行
|
||||
while ($rows = $this->_adapter->fetch($resource)) {
|
||||
//判断是否有过滤器
|
||||
$result[] = $filter ? call_user_func([&$object, $method], $rows) : $rows;
|
||||
}
|
||||
|
||||
return $result;
|
||||
return $filter ? array_map($filter, $result) : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次取出一行
|
||||
*
|
||||
* @param mixed $query 查询对象
|
||||
* @param array|null $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Typecho_Db_Exception
|
||||
* @param callable|null $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中
|
||||
* @return array|null
|
||||
* @throws DbException
|
||||
*/
|
||||
public function fetchRow($query, ?array $filter = null)
|
||||
public function fetchRow($query, ?callable $filter = null): ?array
|
||||
{
|
||||
$resource = $this->query($query, self::READ);
|
||||
$resource = $this->query($query);
|
||||
|
||||
/** 取出过滤器 */
|
||||
if ($filter) {
|
||||
[$object, $method] = $filter;
|
||||
}
|
||||
|
||||
return ($rows = $this->_adapter->fetch($resource)) ?
|
||||
($filter ? $object->$method($rows) : $rows) :
|
||||
[];
|
||||
return ($rows = $this->adapter->fetch($resource)) ?
|
||||
($filter ? call_user_func($filter, $rows) : $rows) :
|
||||
null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,21 +441,15 @@ class Typecho_Db
|
||||
*
|
||||
* @param mixed $query 查询对象
|
||||
* @param array|null $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Typecho_Db_Exception
|
||||
* @return object|null
|
||||
* @throws DbException
|
||||
*/
|
||||
public function fetchObject($query, ?array $filter = null)
|
||||
public function fetchObject($query, ?array $filter = null): ?object
|
||||
{
|
||||
$resource = $this->query($query, self::READ);
|
||||
$resource = $this->query($query);
|
||||
|
||||
/** 取出过滤器 */
|
||||
if ($filter) {
|
||||
[$object, $method] = $filter;
|
||||
}
|
||||
|
||||
return ($rows = $this->_adapter->fetchObject($resource)) ?
|
||||
($filter ? $object->$method($rows) : $rows) :
|
||||
new stdClass();
|
||||
return ($rows = $this->adapter->fetchObject($resource)) ?
|
||||
($filter ? call_user_func($filter, $rows) : $rows) :
|
||||
null;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
<?php
|
||||
/**
|
||||
* Typecho Blog Platform
|
||||
*
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id: DbAdapter.php 97 2008-04-04 04:39:54Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho\Db;
|
||||
|
||||
use Typecho\Config;
|
||||
use Typecho\Db;
|
||||
|
||||
/**
|
||||
* Typecho数据库适配器
|
||||
@ -13,7 +11,7 @@
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
interface Typecho_Db_Adapter
|
||||
interface Adapter
|
||||
{
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
@ -21,15 +19,15 @@ interface Typecho_Db_Adapter
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable();
|
||||
public static function isAvailable(): bool;
|
||||
|
||||
/**
|
||||
* 数据库连接函数
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @param Config $config 数据库配置
|
||||
* @return mixed
|
||||
*/
|
||||
public function connect(Typecho_Config $config);
|
||||
public function connect(Config $config);
|
||||
|
||||
/**
|
||||
* 获取数据库版本
|
||||
@ -37,16 +35,15 @@ interface Typecho_Db_Adapter
|
||||
* @param mixed $handle
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion($handle);
|
||||
public function getVersion($handle): string;
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table 数据表名
|
||||
* @param mixed $handle 连接对象
|
||||
* @return mixed
|
||||
*/
|
||||
public function truncate($table, $handle);
|
||||
public function truncate(string $table, $handle);
|
||||
|
||||
/**
|
||||
* 执行数据库查询
|
||||
@ -54,35 +51,43 @@ interface Typecho_Db_Adapter
|
||||
* @param string $query 数据库查询SQL字符串
|
||||
* @param mixed $handle 连接对象
|
||||
* @param integer $op 数据库读写状态
|
||||
* @param string $action 数据库动作
|
||||
* @param string $table 数据表
|
||||
* @param string|null $action 数据库动作
|
||||
* @param string|null $table 数据表
|
||||
* @return resource
|
||||
*/
|
||||
public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null);
|
||||
public function query(string $query, $handle, int $op = Db::READ, ?string $action = null, ?string $table = null);
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为数组取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @return array|null
|
||||
*/
|
||||
public function fetch($resource): ?array;
|
||||
|
||||
/**
|
||||
* 将数据查询的结果作为数组全部取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @return array
|
||||
*/
|
||||
public function fetch($resource);
|
||||
public function fetchAll($resource): array;
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为对象取出,其中字段名对应对象属性
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @return object
|
||||
* @return object|null
|
||||
*/
|
||||
public function fetchObject($resource);
|
||||
public function fetchObject($resource): ?object;
|
||||
|
||||
/**
|
||||
* 引号转义函数
|
||||
*
|
||||
* @param string $string 需要转义的字符串
|
||||
* @param mixed $string 需要转义的字符串
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($string);
|
||||
public function quoteValue($string): string;
|
||||
|
||||
/**
|
||||
* 对象引号过滤
|
||||
@ -91,7 +96,7 @@ interface Typecho_Db_Adapter
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn($string);
|
||||
public function quoteColumn(string $string): string;
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
@ -100,7 +105,7 @@ interface Typecho_Db_Adapter
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
*/
|
||||
public function parseSelect(array $sql);
|
||||
public function parseSelect(array $sql): string;
|
||||
|
||||
/**
|
||||
* 取出最后一次查询影响的行数
|
||||
@ -109,7 +114,7 @@ interface Typecho_Db_Adapter
|
||||
* @param mixed $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function affectedRows($resource, $handle);
|
||||
public function affectedRows($resource, $handle): int;
|
||||
|
||||
/**
|
||||
* 取出最后一次插入返回的主键值
|
||||
@ -118,5 +123,5 @@ interface Typecho_Db_Adapter
|
||||
* @param mixed $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function lastInsertId($resource, $handle);
|
||||
public function lastInsertId($resource, $handle): int;
|
||||
}
|
||||
|
18
var/Typecho/Db/Adapter/ConnectionException.php
Normal file
18
var/Typecho/Db/Adapter/ConnectionException.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Typecho\Db\Adapter;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use Typecho\Db\Exception as DbException;
|
||||
|
||||
/**
|
||||
* 数据库连接异常类
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class ConnectionException extends DbException
|
||||
{
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<?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: DbException.php 52 2008-03-18 08:04:01Z magike.net $
|
||||
*/
|
||||
|
||||
/**
|
||||
* 数据库连接异常类
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Adapter_Exception extends Typecho_Db_Exception
|
||||
{}
|
@ -1,196 +0,0 @@
|
||||
<?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: Mysql.php 103 2008-04-09 16:22:43Z magike.net $
|
||||
*/
|
||||
|
||||
/**
|
||||
* 数据库Mysql适配器
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Adapter_Mysql implements Typecho_Db_Adapter
|
||||
{
|
||||
/**
|
||||
* 数据库连接字符串标示
|
||||
*
|
||||
* @access private
|
||||
* @var resource
|
||||
*/
|
||||
private $_dbLink;
|
||||
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
{
|
||||
return function_exists('mysql_connect');
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库连接函数
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @return mixed
|
||||
* @throws Typecho_Db_Exception
|
||||
*/
|
||||
public function connect(Typecho_Config $config)
|
||||
{
|
||||
if ($this->_dbLink = @mysql_connect($config->host . (empty($config->port) ? '' : ':' . $config->port),
|
||||
$config->user, $config->password, true)) {
|
||||
if (@mysql_select_db($config->database, $this->_dbLink)) {
|
||||
if ($config->charset) {
|
||||
mysql_query("SET NAMES '{$config->charset}'", $this->_dbLink);
|
||||
}
|
||||
return $this->_dbLink;
|
||||
}
|
||||
}
|
||||
|
||||
/** 数据库异常 */
|
||||
throw new Typecho_Db_Adapter_Exception(@mysql_error($this->_dbLink));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库版本
|
||||
*
|
||||
* @param mixed $handle
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion($handle)
|
||||
{
|
||||
return 'mysql:mysql ' . mysql_get_server_info($handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table
|
||||
* @param mixed $handle 连接对象
|
||||
* @return mixed|void
|
||||
* @throws Typecho_Db_Exception
|
||||
*/
|
||||
public function truncate($table, $handle)
|
||||
{
|
||||
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table), $handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行数据库查询
|
||||
*
|
||||
* @param string $query 数据库查询SQL字符串
|
||||
* @param mixed $handle 连接对象
|
||||
* @param integer $op 数据库读写状态
|
||||
* @param string $action 数据库动作
|
||||
* @param string $table 数据表
|
||||
* @return resource
|
||||
* @throws Typecho_Db_Exception
|
||||
*/
|
||||
public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null)
|
||||
{
|
||||
if ($resource = @mysql_query($query, $handle)) {
|
||||
return $resource;
|
||||
}
|
||||
|
||||
/** 数据库异常 */
|
||||
throw new Typecho_Db_Query_Exception(@mysql_error($this->_dbLink), mysql_errno($this->_dbLink));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象引号过滤
|
||||
*
|
||||
* @access public
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn($string)
|
||||
{
|
||||
return '`' . $string . '`';
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为数组取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param resource $resource 查询返回资源标识
|
||||
* @return array
|
||||
*/
|
||||
public function fetch($resource)
|
||||
{
|
||||
return mysql_fetch_assoc($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为对象取出,其中字段名对应对象属性
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @return object
|
||||
*/
|
||||
public function fetchObject($resource)
|
||||
{
|
||||
return mysql_fetch_object($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 引号转义函数
|
||||
*
|
||||
* @param string $string 需要转义的字符串
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($string)
|
||||
{
|
||||
return '\'' . str_replace(['\'', '\\'], ['\'\'', '\\\\'], $string) . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
*/
|
||||
public function parseSelect(array $sql)
|
||||
{
|
||||
if (!empty($sql['join'])) {
|
||||
foreach ($sql['join'] as $val) {
|
||||
[$table, $condition, $op] = $val;
|
||||
$sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}";
|
||||
}
|
||||
}
|
||||
|
||||
$sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit'];
|
||||
$sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset'];
|
||||
|
||||
return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
|
||||
$sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次查询影响的行数
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function affectedRows($resource, $handle)
|
||||
{
|
||||
return mysql_affected_rows($handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次插入返回的主键值
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function lastInsertId($resource, $handle)
|
||||
{
|
||||
return mysql_insert_id($handle);
|
||||
}
|
||||
}
|
32
var/Typecho/Db/Adapter/MysqlTrait.php
Normal file
32
var/Typecho/Db/Adapter/MysqlTrait.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Typecho\Db\Adapter;
|
||||
|
||||
trait MysqlTrait
|
||||
{
|
||||
use QueryTrait;
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table
|
||||
* @param mixed $handle 连接对象
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function truncate(string $table, $handle)
|
||||
{
|
||||
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table), $handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
*/
|
||||
public function parseSelect(array $sql): string
|
||||
{
|
||||
return $this->buildQuery($sql);
|
||||
}
|
||||
}
|
@ -1,27 +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: Mysqli.php 103 2008-04-09 16:22:43Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho\Db\Adapter;
|
||||
|
||||
use Typecho\Config;
|
||||
use Typecho\Db;
|
||||
use Typecho\Db\Adapter;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库Mysqli适配器
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter
|
||||
class Mysqli implements Adapter
|
||||
{
|
||||
use MysqlTrait;
|
||||
|
||||
/**
|
||||
* 数据库连接字符串标示
|
||||
*
|
||||
* @access private
|
||||
* @var mysqli
|
||||
* @var \mysqli
|
||||
*/
|
||||
private $_dbLink;
|
||||
private $dbLink;
|
||||
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
@ -29,36 +33,38 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
public static function isAvailable(): bool
|
||||
{
|
||||
return class_exists('MySQLi');
|
||||
return extension_loaded('mysqli');
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库连接函数
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @return mixed
|
||||
* @throws Typecho_Db_Exception
|
||||
* @param Config $config 数据库配置
|
||||
* @return \mysqli
|
||||
* @throws ConnectionException
|
||||
*/
|
||||
public function connect(Typecho_Config $config)
|
||||
public function connect(Config $config): \mysqli
|
||||
{
|
||||
|
||||
if ($this->_dbLink = @mysqli_connect(
|
||||
$config->host,
|
||||
$config->user,
|
||||
$config->password,
|
||||
$config->database,
|
||||
(empty($config->port) ? null : $config->port))
|
||||
if (
|
||||
$this->dbLink = @mysqli_connect(
|
||||
$config->host,
|
||||
$config->user,
|
||||
$config->password,
|
||||
$config->database,
|
||||
(empty($config->port) ? null : $config->port)
|
||||
)
|
||||
) {
|
||||
if ($config->charset) {
|
||||
$this->_dbLink->query("SET NAMES '{$config->charset}'");
|
||||
$this->dbLink->query("SET NAMES '{$config->charset}'");
|
||||
}
|
||||
return $this->_dbLink;
|
||||
return $this->dbLink;
|
||||
}
|
||||
|
||||
/** 数据库异常 */
|
||||
throw new Typecho_Db_Adapter_Exception(@$this->_dbLink->error);
|
||||
throw new ConnectionException(@$this->dbLink->error, @$this->dbLink->errno);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,22 +73,9 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter
|
||||
* @param mixed $handle
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion($handle)
|
||||
public function getVersion($handle): string
|
||||
{
|
||||
return 'mysqli:mysql ' . $this->_dbLink->server_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table
|
||||
* @param mixed $handle 连接对象
|
||||
* @return mixed|void
|
||||
* @throws Typecho_Db_Exception
|
||||
*/
|
||||
public function truncate($table, $handle)
|
||||
{
|
||||
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table), $handle);
|
||||
return 'mysqli:mysql ' . $this->dbLink->server_version;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,19 +84,24 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter
|
||||
* @param string $query 数据库查询SQL字符串
|
||||
* @param mixed $handle 连接对象
|
||||
* @param integer $op 数据库读写状态
|
||||
* @param string $action 数据库动作
|
||||
* @param string $table 数据表
|
||||
* @return resource
|
||||
* @throws Typecho_Db_Exception
|
||||
* @param string|null $action 数据库动作
|
||||
* @param string|null $table 数据表
|
||||
* @return \mysqli_result
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null)
|
||||
{
|
||||
if ($resource = @$this->_dbLink->query($query)) {
|
||||
public function query(
|
||||
string $query,
|
||||
$handle,
|
||||
int $op = Db::READ,
|
||||
?string $action = null,
|
||||
?string $table = null
|
||||
): \mysqli_result {
|
||||
if ($resource = @$this->dbLink->query($query)) {
|
||||
return $resource;
|
||||
}
|
||||
|
||||
/** 数据库异常 */
|
||||
throw new Typecho_Db_Query_Exception($this->_dbLink->error, $this->_dbLink->errno);
|
||||
throw new SQLException($this->dbLink->error, $this->dbLink->errno);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,29 +111,40 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn($string)
|
||||
public function quoteColumn(string $string): string
|
||||
{
|
||||
return $this->_dbLink->real_escape_string($string);
|
||||
return $this->dbLink->real_escape_string($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为数组取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param resource $resource 查询返回资源标识
|
||||
* @return array
|
||||
* @param \mysqli_result $resource 查询返回资源标识
|
||||
* @return array|null
|
||||
*/
|
||||
public function fetch($resource)
|
||||
public function fetch($resource): ?array
|
||||
{
|
||||
return $resource->fetch_assoc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的结果作为数组全部取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param \mysqli_result $resource 查询返回资源标识
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll($resource): array
|
||||
{
|
||||
return $resource->fetch_all(MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为对象取出,其中字段名对应对象属性
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @return object
|
||||
* @param \mysqli_result $resource 查询的资源数据
|
||||
* @return object|null
|
||||
*/
|
||||
public function fetchObject($resource)
|
||||
public function fetchObject($resource): ?object
|
||||
{
|
||||
return $resource->fetch_object();
|
||||
}
|
||||
@ -143,58 +152,35 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter
|
||||
/**
|
||||
* 引号转义函数
|
||||
*
|
||||
* @param string $string 需要转义的字符串
|
||||
* @param mixed $string 需要转义的字符串
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($string)
|
||||
public function quoteValue($string): string
|
||||
{
|
||||
return '\'' . str_replace(['\'', '\\'], ['\'\'', '\\\\'], $string) . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
* 取出最后一次查询影响的行数
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
* @param \mysqli_result $resource 查询的资源数据
|
||||
* @param \mysqli $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function parseSelect(array $sql)
|
||||
public function affectedRows($resource, $handle): int
|
||||
{
|
||||
if (!empty($sql['join'])) {
|
||||
foreach ($sql['join'] as $val) {
|
||||
[$table, $condition, $op] = $val;
|
||||
$sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}";
|
||||
}
|
||||
}
|
||||
|
||||
$sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit'];
|
||||
$sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset'];
|
||||
|
||||
return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
|
||||
$sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
|
||||
return $handle->affected_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次查询影响的行数
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function affectedRows($resource, $handle)
|
||||
{
|
||||
return $this->_dbLink->affected_rows;
|
||||
}
|
||||
|
||||
/*y
|
||||
* 取出最后一次插入返回的主键值
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @param \mysqli_result $resource 查询的资源数据
|
||||
* @param \mysqli $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function lastInsertId($resource, $handle)
|
||||
public function lastInsertId($resource, $handle): int
|
||||
{
|
||||
return $this->_dbLink->insert_id;
|
||||
return $handle->insert_id;
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,29 @@
|
||||
<?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: Mysql.php 89 2008-03-31 00:10:57Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho\Db\Adapter;
|
||||
|
||||
use Typecho\Config;
|
||||
use Typecho\Db;
|
||||
use Typecho\Db\Adapter;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库PDOMysql适配器
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter
|
||||
abstract class Pdo implements Adapter
|
||||
{
|
||||
/**
|
||||
* 数据库对象
|
||||
*
|
||||
* @access protected
|
||||
* @var PDO
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $_object;
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* 最后一次操作的数据表
|
||||
@ -29,7 +31,7 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $_lastTable;
|
||||
protected $lastTable;
|
||||
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
@ -37,7 +39,7 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
public static function isAvailable(): bool
|
||||
{
|
||||
return class_exists('PDO');
|
||||
}
|
||||
@ -45,31 +47,31 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter
|
||||
/**
|
||||
* 数据库连接函数
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @return PDO
|
||||
* @throws Typecho_Db_Exception
|
||||
* @param Config $config 数据库配置
|
||||
* @return \PDO
|
||||
* @throws ConnectionException
|
||||
*/
|
||||
public function connect(Typecho_Config $config)
|
||||
public function connect(Config $config): \PDO
|
||||
{
|
||||
try {
|
||||
$this->_object = $this->init($config);
|
||||
$this->_object->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
return $this->_object;
|
||||
} catch (PDOException $e) {
|
||||
$this->object = $this->init($config);
|
||||
$this->object->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
return $this->object;
|
||||
} catch (\PDOException $e) {
|
||||
/** 数据库异常 */
|
||||
throw new Typecho_Db_Adapter_Exception($e->getMessage());
|
||||
throw new ConnectionException($e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据库
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @param Config $config 数据库配置
|
||||
* @abstract
|
||||
* @access public
|
||||
* @return PDO
|
||||
* @return \PDO
|
||||
*/
|
||||
abstract public function init(Typecho_Config $config);
|
||||
abstract public function init(Config $config): \PDO;
|
||||
|
||||
/**
|
||||
* 获取数据库版本
|
||||
@ -77,78 +79,94 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter
|
||||
* @param mixed $handle
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion($handle)
|
||||
public function getVersion($handle): string
|
||||
{
|
||||
return 'pdo:' . $handle->getAttribute(PDO::ATTR_DRIVER_NAME)
|
||||
. ' ' . $handle->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
return 'pdo:' . $handle->getAttribute(\PDO::ATTR_DRIVER_NAME)
|
||||
. ' ' . $handle->getAttribute(\PDO::ATTR_SERVER_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行数据库查询
|
||||
*
|
||||
* @param string $query 数据库查询SQL字符串
|
||||
* @param mixed $handle 连接对象
|
||||
* @param \PDO $handle 连接对象
|
||||
* @param integer $op 数据库读写状态
|
||||
* @param string $action 数据库动作
|
||||
* @param string $table 数据表
|
||||
* @return resource
|
||||
* @throws Typecho_Db_Exception
|
||||
* @param string|null $action 数据库动作
|
||||
* @param string|null $table 数据表
|
||||
* @return \PDOStatement
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null)
|
||||
{
|
||||
public function query(
|
||||
string $query,
|
||||
$handle,
|
||||
int $op = Db::READ,
|
||||
?string $action = null,
|
||||
?string $table = null
|
||||
): \PDOStatement {
|
||||
try {
|
||||
$this->_lastTable = $table;
|
||||
$this->lastTable = $table;
|
||||
$resource = $handle->prepare($query);
|
||||
$resource->execute();
|
||||
} catch (PDOException $e) {
|
||||
} catch (\PDOException $e) {
|
||||
/** 数据库异常 */
|
||||
throw new Typecho_Db_Query_Exception($e->getMessage(), $e->getCode());
|
||||
throw new SQLException($e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
return $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为数组取出,其中字段名对应数组键值
|
||||
* 将数据查询的结果作为数组全部取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param resource $resource 查询返回资源标识
|
||||
* @param \PDOStatement $resource 查询的资源数据
|
||||
* @return array
|
||||
*/
|
||||
public function fetch($resource)
|
||||
public function fetchAll($resource): array
|
||||
{
|
||||
return $resource->fetch(PDO::FETCH_ASSOC);
|
||||
return $resource->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为数组取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param \PDOStatement $resource 查询返回资源标识
|
||||
* @return array|null
|
||||
*/
|
||||
public function fetch($resource): ?array
|
||||
{
|
||||
return $resource->fetch(\PDO::FETCH_ASSOC) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为对象取出,其中字段名对应对象属性
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @return object
|
||||
* @param \PDOStatement $resource 查询的资源数据
|
||||
* @return object|null
|
||||
*/
|
||||
public function fetchObject($resource)
|
||||
public function fetchObject($resource): ?object
|
||||
{
|
||||
return $resource->fetchObject();
|
||||
return $resource->fetchObject() ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 引号转义函数
|
||||
*
|
||||
* @param string $string 需要转义的字符串
|
||||
* @param mixed $string 需要转义的字符串
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($string)
|
||||
public function quoteValue($string): string
|
||||
{
|
||||
return $this->_object->quote($string);
|
||||
return $this->object->quote($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次查询影响的行数
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @param \PDOStatement $resource 查询的资源数据
|
||||
* @param \PDO $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function affectedRows($resource, $handle)
|
||||
public function affectedRows($resource, $handle): int
|
||||
{
|
||||
return $resource->rowCount();
|
||||
}
|
||||
@ -156,11 +174,11 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter
|
||||
/**
|
||||
* 取出最后一次插入返回的主键值
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @param \PDOStatement $resource 查询的资源数据
|
||||
* @param \PDO $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function lastInsertId($resource, $handle)
|
||||
public function lastInsertId($resource, $handle): int
|
||||
{
|
||||
return $handle->lastInsertId();
|
||||
}
|
||||
|
@ -1,42 +1,33 @@
|
||||
<?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: Mysql.php 89 2008-03-31 00:10:57Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho\Db\Adapter\Pdo;
|
||||
|
||||
use Typecho\Config;
|
||||
use Typecho\Db\Adapter\MysqlTrait;
|
||||
use Typecho\Db\Adapter\Pdo;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库Pdo_Mysql适配器
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Adapter_Pdo_Mysql extends Typecho_Db_Adapter_Pdo
|
||||
class Mysql extends Pdo
|
||||
{
|
||||
use MysqlTrait;
|
||||
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
public static function isAvailable(): bool
|
||||
{
|
||||
return parent::isAvailable() && in_array('mysql', PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table
|
||||
* @param mixed $handle 连接对象
|
||||
* @return mixed|void
|
||||
* @throws Typecho_Db_Exception
|
||||
*/
|
||||
public function truncate($table, $handle)
|
||||
{
|
||||
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table), $handle);
|
||||
return parent::isAvailable() && in_array('mysql', \PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,7 +37,7 @@ class Typecho_Db_Adapter_Pdo_Mysql extends Typecho_Db_Adapter_Pdo
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn($string)
|
||||
public function quoteColumn(string $string): string
|
||||
{
|
||||
return '`' . $string . '`';
|
||||
}
|
||||
@ -54,50 +45,35 @@ class Typecho_Db_Adapter_Pdo_Mysql extends Typecho_Db_Adapter_Pdo
|
||||
/**
|
||||
* 初始化数据库
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @param Config $config 数据库配置
|
||||
* @access public
|
||||
* @return PDO
|
||||
* @return \PDO
|
||||
*/
|
||||
public function init(Typecho_Config $config)
|
||||
public function init(Config $config): \PDO
|
||||
{
|
||||
$pdo = new PDO(!empty($config->dsn) ? $config->dsn :
|
||||
"mysql:dbname={$config->database};host={$config->host};port={$config->port}", $config->user, $config->password);
|
||||
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
$pdo->exec("SET NAMES '{$config->charset}'");
|
||||
$pdo = new \PDO(
|
||||
!empty($config->dsn)
|
||||
? $config->dsn : "mysql:dbname={$config->database};host={$config->host};port={$config->port}",
|
||||
$config->user,
|
||||
$config->password
|
||||
);
|
||||
$pdo->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
|
||||
if ($config->charset) {
|
||||
$pdo->exec("SET NAMES '{$config->charset}'");
|
||||
}
|
||||
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 引号转义函数
|
||||
*
|
||||
* @param string $string 需要转义的字符串
|
||||
* @param mixed $string 需要转义的字符串
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($string)
|
||||
public function quoteValue($string): string
|
||||
{
|
||||
return '\'' . str_replace(['\'', '\\'], ['\'\'', '\\\\'], $string) . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
*/
|
||||
public function parseSelect(array $sql)
|
||||
{
|
||||
if (!empty($sql['join'])) {
|
||||
foreach ($sql['join'] as $val) {
|
||||
[$table, $condition, $op] = $val;
|
||||
$sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}";
|
||||
}
|
||||
}
|
||||
|
||||
$sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit'];
|
||||
$sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset'];
|
||||
|
||||
return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
|
||||
$sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
|
||||
}
|
||||
}
|
||||
|
@ -1,33 +1,25 @@
|
||||
<?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 Typecho\Db\Adapter\Pdo;
|
||||
|
||||
use Typecho\Config;
|
||||
use Typecho\Db;
|
||||
use Typecho\Db\Adapter\SQLException;
|
||||
use Typecho\Db\Adapter\Pdo;
|
||||
use Typecho\Db\Adapter\PgsqlTrait;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库Pdo_Pgsql适配器
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo
|
||||
class Pgsql extends Pdo
|
||||
{
|
||||
/**
|
||||
* 主键列表
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_pk = [];
|
||||
|
||||
/**
|
||||
* 兼容的插入模式
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $_compatibleInsert = false;
|
||||
use PgsqlTrait;
|
||||
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
@ -35,134 +27,51 @@ class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
public static function isAvailable(): bool
|
||||
{
|
||||
return parent::isAvailable() && in_array('pgsql', PDO::getAvailableDrivers());
|
||||
return parent::isAvailable() && in_array('pgsql', \PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
* 执行数据库查询
|
||||
*
|
||||
* @param string $table
|
||||
* @param mixed $handle 连接对象
|
||||
* @return mixed|void
|
||||
* @throws Typecho_Db_Exception
|
||||
* @param string $query 数据库查询SQL字符串
|
||||
* @param \PDO $handle 连接对象
|
||||
* @param integer $op 数据库读写状态
|
||||
* @param string|null $action 数据库动作
|
||||
* @param string|null $table 数据表
|
||||
* @return \PDOStatement
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function truncate($table, $handle)
|
||||
{
|
||||
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table) . ' RESTART IDENTITY', $handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖标准动作
|
||||
* fix #710
|
||||
*
|
||||
* @param string $query
|
||||
* @param mixed $handle
|
||||
* @param int $op
|
||||
* @param null $action
|
||||
* @param null $table
|
||||
* @return resource
|
||||
* @throws Typecho_Db_Exception
|
||||
*/
|
||||
public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null)
|
||||
{
|
||||
if (Typecho_Db::INSERT == $action && !empty($table)) {
|
||||
if (!isset($this->_pk[$table])) {
|
||||
$result = $handle->query("SELECT
|
||||
pg_attribute.attname,
|
||||
format_type(pg_attribute.atttypid, pg_attribute.atttypmod)
|
||||
FROM pg_index, pg_class, pg_attribute, pg_namespace
|
||||
WHERE
|
||||
pg_class.oid = " . $this->quoteValue($table) . "::regclass AND
|
||||
indrelid = pg_class.oid AND
|
||||
nspname = 'public' AND
|
||||
pg_class.relnamespace = pg_namespace.oid AND
|
||||
pg_attribute.attrelid = pg_class.oid AND
|
||||
pg_attribute.attnum = any(pg_index.indkey)
|
||||
AND indisprimary")->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!empty($result)) {
|
||||
$this->_pk[$table] = $result['attname'];
|
||||
}
|
||||
}
|
||||
|
||||
// 使用兼容模式监听插入结果
|
||||
if (isset($this->_pk[$table])) {
|
||||
$this->_compatibleInsert = true;
|
||||
$query .= ' RETURNING ' . $this->quoteColumn($this->_pk[$table]);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::query($query, $handle, $op, $action, $table); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象引号过滤
|
||||
*
|
||||
* @access public
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn($string)
|
||||
{
|
||||
return '"' . $string . '"';
|
||||
public function query(
|
||||
string $query,
|
||||
$handle,
|
||||
int $op = Db::READ,
|
||||
?string $action = null,
|
||||
?string $table = null
|
||||
): \PDOStatement {
|
||||
$this->prepareQuery($query, $handle, $action, $table);
|
||||
return parent::query($query, $handle, $op, $action, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据库
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @access public
|
||||
* @return PDO
|
||||
* @param Config $config 数据库配置
|
||||
* @return \PDO
|
||||
*/
|
||||
public function init(Typecho_Config $config)
|
||||
public function init(Config $config): \PDO
|
||||
{
|
||||
$pdo = new PDO("pgsql:dbname={$config->database};host={$config->host};port={$config->port}", $config->user, $config->password);
|
||||
$pdo->exec("SET NAMES '{$config->charset}'");
|
||||
$pdo = new \PDO(
|
||||
"pgsql:dbname={$config->database};host={$config->host};port={$config->port}",
|
||||
$config->user,
|
||||
$config->password
|
||||
);
|
||||
|
||||
if ($config->charset) {
|
||||
$pdo->exec("SET NAMES '{$config->charset}'");
|
||||
}
|
||||
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
*/
|
||||
public function parseSelect(array $sql)
|
||||
{
|
||||
if (!empty($sql['join'])) {
|
||||
foreach ($sql['join'] as $val) {
|
||||
[$table, $condition, $op] = $val;
|
||||
$sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}";
|
||||
}
|
||||
}
|
||||
|
||||
$sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit'];
|
||||
$sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset'];
|
||||
|
||||
return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
|
||||
$sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次插入返回的主键值
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function lastInsertId($resource, $handle)
|
||||
{
|
||||
if ($this->_compatibleInsert) {
|
||||
$this->_compatibleInsert = false;
|
||||
return $resource->fetchColumn(0);
|
||||
} elseif ($handle->query('SELECT oid FROM pg_class WHERE relname = ' . $this->quoteValue($this->_lastTable . '_seq'))->fetchAll()) {
|
||||
/** 查看是否存在序列,可能需要更严格的检查 */
|
||||
return $handle->lastInsertId($this->_lastTable . '_seq');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,23 @@
|
||||
<?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 Typecho\Db\Adapter\Pdo;
|
||||
|
||||
use Typecho\Config;
|
||||
use Typecho\Db\Adapter\Pdo;
|
||||
use Typecho\Db\Adapter\SQLiteTrait;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库Pdo_SQLite适配器
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo
|
||||
class SQLite extends Pdo
|
||||
{
|
||||
/**
|
||||
* @var sqlite version 2.x
|
||||
*/
|
||||
private $_isSQLite2 = false;
|
||||
use SQLiteTrait;
|
||||
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
@ -26,94 +25,57 @@ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
public static function isAvailable(): bool
|
||||
{
|
||||
return parent::isAvailable() && in_array('sqlite', PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table
|
||||
* @param mixed $handle 连接对象
|
||||
* @return mixed|void
|
||||
* @throws Typecho_Db_Exception
|
||||
*/
|
||||
public function truncate($table, $handle)
|
||||
{
|
||||
$this->query('DELETE FROM ' . $this->quoteColumn($table), $handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象引号过滤
|
||||
*
|
||||
* @access public
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn($string)
|
||||
{
|
||||
return '"' . $string . '"';
|
||||
return parent::isAvailable() && in_array('sqlite', \PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据库
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @param Config $config 数据库配置
|
||||
* @access public
|
||||
* @return PDO
|
||||
* @return \PDO
|
||||
*/
|
||||
public function init(Typecho_Config $config)
|
||||
public function init(Config $config): \PDO
|
||||
{
|
||||
$pdo = new PDO("sqlite:{$config->file}");
|
||||
$this->_isSQLite2 = version_compare($pdo->getAttribute(PDO::ATTR_SERVER_VERSION), '3.0.0', '<');
|
||||
$pdo = new \PDO("sqlite:{$config->file}");
|
||||
$this->isSQLite2 = version_compare($pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '3.0.0', '<');
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $resource
|
||||
* @return object
|
||||
* 将数据查询的其中一行作为对象取出,其中字段名对应对象属性
|
||||
*
|
||||
* @param \PDOStatement $resource 查询的资源数据
|
||||
* @return object|null
|
||||
*/
|
||||
public function fetchObject($resource)
|
||||
public function fetchObject($resource): ?object
|
||||
{
|
||||
return (object)$this->fetch($resource);
|
||||
$result = $this->fetch($resource);
|
||||
return $result ? (object) $result : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $resource
|
||||
* 将数据查询的其中一行作为数组取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param \PDOStatement $resource 查询返回资源标识
|
||||
* @return array|null
|
||||
*/
|
||||
public function fetch($resource): ?array
|
||||
{
|
||||
$result = parent::fetch($resource);
|
||||
return $result ? $this->filterColumnName($result) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的结果作为数组全部取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param \PDOStatement $resource 查询的资源数据
|
||||
* @return array
|
||||
*/
|
||||
public function fetch($resource)
|
||||
public function fetchAll($resource): array
|
||||
{
|
||||
return Typecho_Common::filterSQLite2ColumnName(parent::fetch($resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
*/
|
||||
public function parseSelect(array $sql)
|
||||
{
|
||||
if (!empty($sql['join'])) {
|
||||
foreach ($sql['join'] as $val) {
|
||||
[$table, $condition, $op] = $val;
|
||||
$sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}";
|
||||
}
|
||||
}
|
||||
|
||||
$sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit'];
|
||||
$sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset'];
|
||||
|
||||
$query = 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
|
||||
$sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
|
||||
|
||||
if ($this->_isSQLite2) {
|
||||
$query = Typecho_Common::filterSQLite2CountQuery($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
return array_map([$this, 'filterColumnName'], parent::fetchAll($resource));
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,23 @@
|
||||
<?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 Typecho\Db\Adapter;
|
||||
|
||||
use Typecho\Config;
|
||||
use Typecho\Db;
|
||||
use Typecho\Db\Adapter;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库Pgsql适配器
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter
|
||||
class Pgsql implements Adapter
|
||||
{
|
||||
/**
|
||||
* 最后一次操作的数据表
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $_lastTable;
|
||||
/**
|
||||
* 数据库连接字符串标示
|
||||
*
|
||||
* @access private
|
||||
* @var resource
|
||||
*/
|
||||
private $_dbLink;
|
||||
use PgsqlTrait;
|
||||
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
@ -36,29 +25,32 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
public static function isAvailable(): bool
|
||||
{
|
||||
return function_exists('pg_connect');
|
||||
return extension_loaded('pgsql');
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库连接函数
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @param Config $config 数据库配置
|
||||
* @return resource
|
||||
* @throws Typecho_Db_Exception
|
||||
* @throws ConnectionException
|
||||
*/
|
||||
public function connect(Typecho_Config $config)
|
||||
public function connect(Config $config)
|
||||
{
|
||||
if ($this->_dbLink = @pg_connect("host={$config->host} port={$config->port} dbname={$config->database} user={$config->user} password={$config->password}")) {
|
||||
if (
|
||||
$dbLink = pg_connect("host={$config->host} port={$config->port}"
|
||||
. " dbname={$config->database} user={$config->user} password={$config->password}")
|
||||
) {
|
||||
if ($config->charset) {
|
||||
pg_query($this->_dbLink, "SET NAMES '{$config->charset}'");
|
||||
pg_query($dbLink, "SET NAMES '{$config->charset}'");
|
||||
}
|
||||
return $this->_dbLink;
|
||||
return $dbLink;
|
||||
}
|
||||
|
||||
/** 数据库异常 */
|
||||
throw new Typecho_Db_Adapter_Exception(@pg_last_error($this->_dbLink));
|
||||
throw new ConnectionException(pg_last_error($dbLink));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,141 +59,87 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter
|
||||
* @param mixed $handle
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion($handle)
|
||||
public function getVersion($handle): string
|
||||
{
|
||||
$version = pg_version($handle);
|
||||
return 'pgsql:pgsql ' . $version['server'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table
|
||||
* @param mixed $handle 连接对象
|
||||
* @return mixed|void
|
||||
* @throws Typecho_Db_Exception
|
||||
*/
|
||||
public function truncate($table, $handle)
|
||||
{
|
||||
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table) . ' RESTART IDENTITY', $handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行数据库查询
|
||||
*
|
||||
* @param string $query 数据库查询SQL字符串
|
||||
* @param mixed $handle 连接对象
|
||||
* @param resource $handle 连接对象
|
||||
* @param integer $op 数据库读写状态
|
||||
* @param string $action 数据库动作
|
||||
* @param string $table 数据表
|
||||
* @param string|null $action 数据库动作
|
||||
* @param string|null $table 数据表
|
||||
* @return resource
|
||||
* @throws Typecho_Db_Exception
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null)
|
||||
public function query(string $query, $handle, int $op = Db::READ, ?string $action = null, ?string $table = null)
|
||||
{
|
||||
$this->_lastTable = $table;
|
||||
if ($resource = @pg_query($handle, $query)) {
|
||||
$this->prepareQuery($query, $handle, $action, $table);
|
||||
if ($resource = pg_query($handle, $query)) {
|
||||
return $resource;
|
||||
}
|
||||
|
||||
/** 数据库异常 */
|
||||
throw new Typecho_Db_Query_Exception(@pg_last_error($this->_dbLink),
|
||||
pg_result_error_field(pg_get_result($this->_dbLink), PGSQL_DIAG_SQLSTATE));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象引号过滤
|
||||
*
|
||||
* @access public
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn($string)
|
||||
{
|
||||
return '"' . $string . '"';
|
||||
throw new SQLException(
|
||||
@pg_last_error($handle),
|
||||
pg_result_error_field(pg_get_result($handle), PGSQL_DIAG_SQLSTATE)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为数组取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param resource $resource 查询返回资源标识
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
public function fetch($resource)
|
||||
public function fetch($resource): ?array
|
||||
{
|
||||
return pg_fetch_assoc($resource);
|
||||
return pg_fetch_assoc($resource) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为对象取出,其中字段名对应对象属性
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @return object
|
||||
* @return object|null
|
||||
*/
|
||||
public function fetchObject($resource)
|
||||
public function fetchObject($resource): ?object
|
||||
{
|
||||
return pg_fetch_object($resource);
|
||||
return pg_fetch_object($resource) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
* @param resource $resource
|
||||
* @return array|null
|
||||
*/
|
||||
public function parseSelect(array $sql)
|
||||
public function fetchAll($resource): array
|
||||
{
|
||||
if (!empty($sql['join'])) {
|
||||
foreach ($sql['join'] as $val) {
|
||||
[$table, $condition, $op] = $val;
|
||||
$sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}";
|
||||
}
|
||||
}
|
||||
|
||||
$sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit'];
|
||||
$sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset'];
|
||||
|
||||
return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
|
||||
$sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
|
||||
return pg_fetch_all($resource, PGSQL_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次查询影响的行数
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @param resource $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function affectedRows($resource, $handle)
|
||||
public function affectedRows($resource, $handle): int
|
||||
{
|
||||
return pg_affected_rows($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次插入返回的主键值
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function lastInsertId($resource, $handle)
|
||||
{
|
||||
/** 查看是否存在序列,可能需要更严格的检查 */
|
||||
if (pg_fetch_assoc(pg_query($handle, 'SELECT oid FROM pg_class WHERE relname = ' . $this->quoteValue($this->_lastTable . '_seq')))) {
|
||||
return pg_fetch_result(pg_query($handle, 'SELECT CURRVAL(' . $this->quoteValue($this->_lastTable . '_seq') . ')'), 0, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 引号转义函数
|
||||
*
|
||||
* @param string $string 需要转义的字符串
|
||||
* @param mixed $string 需要转义的字符串
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($string)
|
||||
public function quoteValue($string): string
|
||||
{
|
||||
return '\'' . pg_escape_string($string) . '\'';
|
||||
}
|
||||
|
167
var/Typecho/Db/Adapter/PgsqlTrait.php
Normal file
167
var/Typecho/Db/Adapter/PgsqlTrait.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace Typecho\Db\Adapter;
|
||||
|
||||
use Typecho\Db;
|
||||
|
||||
trait PgsqlTrait
|
||||
{
|
||||
use QueryTrait;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $pk = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $compatibleInsert = false;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $lastInsertTable = null;
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table
|
||||
* @param resource $handle 连接对象
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function truncate(string $table, $handle)
|
||||
{
|
||||
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table) . ' RESTART IDENTITY', $handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
*/
|
||||
public function parseSelect(array $sql): string
|
||||
{
|
||||
return $this->buildQuery($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象引号过滤
|
||||
*
|
||||
* @access public
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn(string $string): string
|
||||
{
|
||||
return '"' . $string . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
* @param $handle
|
||||
* @param string|null $action
|
||||
* @param string|null $table
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function prepareQuery(string &$query, $handle, ?string $action = null, ?string $table = null)
|
||||
{
|
||||
if (Db::INSERT == $action && !empty($table)) {
|
||||
$this->compatibleInsert = false;
|
||||
|
||||
if (!isset($this->pk[$table])) {
|
||||
$resource = $this->query("SELECT
|
||||
pg_attribute.attname,
|
||||
format_type(pg_attribute.atttypid, pg_attribute.atttypmod)
|
||||
FROM pg_index, pg_class, pg_attribute, pg_namespace
|
||||
WHERE
|
||||
pg_class.oid = " . $this->quoteValue($table) . "::regclass AND
|
||||
indrelid = pg_class.oid AND
|
||||
nspname = 'public' AND
|
||||
pg_class.relnamespace = pg_namespace.oid AND
|
||||
pg_attribute.attrelid = pg_class.oid AND
|
||||
pg_attribute.attnum = any(pg_index.indkey)
|
||||
AND indisprimary", $handle, Db::READ, Db::SELECT, $table);
|
||||
|
||||
$result = $this->fetch($resource);
|
||||
|
||||
if (!empty($result)) {
|
||||
$this->pk[$table] = $result['attname'];
|
||||
}
|
||||
}
|
||||
|
||||
// 使用兼容模式监听插入结果
|
||||
if (isset($this->pk[$table])) {
|
||||
$this->compatibleInsert = true;
|
||||
$this->lastInsertTable = $table;
|
||||
$query .= ' RETURNING ' . $this->quoteColumn($this->pk[$table]);
|
||||
}
|
||||
} else {
|
||||
$this->lastInsertTable = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次插入返回的主键值
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param resource $handle 连接对象
|
||||
* @return integer
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function lastInsertId($resource, $handle): int
|
||||
{
|
||||
$lastTable = $this->lastInsertTable;
|
||||
|
||||
if ($this->compatibleInsert) {
|
||||
$result = $this->fetch($resource);
|
||||
$pk = $this->pk[$lastTable];
|
||||
|
||||
if (!empty($result) && isset($result[$pk])) {
|
||||
return (int) $result[$pk];
|
||||
}
|
||||
} else {
|
||||
$resource = $this->query(
|
||||
'SELECT oid FROM pg_class WHERE relname = '
|
||||
. $this->quoteValue($lastTable . '_seq'),
|
||||
$handle,
|
||||
Db::READ,
|
||||
Db::SELECT,
|
||||
$lastTable
|
||||
);
|
||||
|
||||
$result = $this->fetch($resource);
|
||||
|
||||
if (!empty($result)) {
|
||||
$resource = $this->query(
|
||||
'SELECT CURRVAL(' . $this->quoteValue($lastTable . '_seq') . ') AS last_insert_id',
|
||||
$handle,
|
||||
Db::READ,
|
||||
Db::SELECT,
|
||||
$lastTable
|
||||
);
|
||||
|
||||
$result = $this->fetch($resource);
|
||||
if (!empty($result)) {
|
||||
return (int) $result['last_insert_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
abstract public function query(
|
||||
string $query,
|
||||
$handle,
|
||||
int $op = Db::READ,
|
||||
?string $action = null,
|
||||
?string $table = null
|
||||
);
|
||||
|
||||
abstract public function quoteValue(string $string): string;
|
||||
|
||||
abstract public function fetch($resource): ?array;
|
||||
}
|
29
var/Typecho/Db/Adapter/QueryTrait.php
Normal file
29
var/Typecho/Db/Adapter/QueryTrait.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Typecho\Db\Adapter;
|
||||
|
||||
/**
|
||||
* Build Sql
|
||||
*/
|
||||
trait QueryTrait
|
||||
{
|
||||
/**
|
||||
* @param array $sql
|
||||
* @return string
|
||||
*/
|
||||
private function buildQuery(array $sql): string
|
||||
{
|
||||
if (!empty($sql['join'])) {
|
||||
foreach ($sql['join'] as $val) {
|
||||
[$table, $condition, $op] = $val;
|
||||
$sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}";
|
||||
}
|
||||
}
|
||||
|
||||
$sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit'];
|
||||
$sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset'];
|
||||
|
||||
return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
|
||||
$sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
|
||||
}
|
||||
}
|
18
var/Typecho/Db/Adapter/SQLException.php
Normal file
18
var/Typecho/Db/Adapter/SQLException.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Typecho\Db\Adapter;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use Typecho\Db\Exception as DbException;
|
||||
|
||||
/**
|
||||
* 数据库连接异常类
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class SQLException extends DbException
|
||||
{
|
||||
}
|
@ -1,27 +1,23 @@
|
||||
<?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: Mysql.php 103 2008-04-09 16:22:43Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho\Db\Adapter;
|
||||
|
||||
use Typecho\Config;
|
||||
use Typecho\Db;
|
||||
use Typecho\Db\Adapter;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库SQLite适配器
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter
|
||||
class SQLite implements Adapter
|
||||
{
|
||||
/**
|
||||
* 数据库标示
|
||||
*
|
||||
* @access private
|
||||
* @var resource
|
||||
*/
|
||||
private $_dbHandle;
|
||||
use SQLiteTrait;
|
||||
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
@ -29,26 +25,28 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
public static function isAvailable(): bool
|
||||
{
|
||||
return function_exists('sqlite_open');
|
||||
return extension_loaded('sqlite3');
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库连接函数
|
||||
*
|
||||
* @param Typecho_Config $config 数据库配置
|
||||
* @return resource
|
||||
* @throws Typecho_Db_Exception
|
||||
* @param Config $config 数据库配置
|
||||
* @return \SQLite3
|
||||
* @throws ConnectionException
|
||||
*/
|
||||
public function connect(Typecho_Config $config)
|
||||
public function connect(Config $config): \SQLite3
|
||||
{
|
||||
if ($this->_dbHandle = sqlite_open($config->file, 0666, $error)) {
|
||||
return $this->_dbHandle;
|
||||
try {
|
||||
$dbHandle = new \SQLite3($config->file);
|
||||
$this->isSQLite2 = version_compare(\SQLite3::version()['versionString'], '3.0.0', '<');
|
||||
} catch (\Exception $e) {
|
||||
throw new ConnectionException($e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
/** 数据库异常 */
|
||||
throw new Typecho_Db_Adapter_Exception($error);
|
||||
return $dbHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,135 +55,112 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter
|
||||
* @param mixed $handle
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion($handle)
|
||||
public function getVersion($handle): string
|
||||
{
|
||||
return 'sqlite:sqlite ' . sqlite_libversion();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table
|
||||
* @param mixed $handle 连接对象
|
||||
* @return mixed|void
|
||||
* @throws Typecho_Db_Exception
|
||||
*/
|
||||
public function truncate($table, $handle)
|
||||
{
|
||||
$this->query('DELETE FROM ' . $this->quoteColumn($table), $handle);
|
||||
return 'sqlite:sqlite ' . \SQLite3::version()['versionString'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行数据库查询
|
||||
*
|
||||
* @param string $query
|
||||
* @param mixed $handle
|
||||
* @param int $op
|
||||
* @param null $action
|
||||
* @param string $table 数据表
|
||||
* @return resource|SQLiteResult
|
||||
* @throws Typecho_Db_Query_Exception
|
||||
* @param string $query 数据库查询SQL字符串
|
||||
* @param \SQLite3 $handle 连接对象
|
||||
* @param integer $op 数据库读写状态
|
||||
* @param string|null $action 数据库动作
|
||||
* @param string|null $table 数据表
|
||||
* @return \SQLite3Result
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function query($query, $handle, $op = Typecho_Db::READ, $action = null, $table = null)
|
||||
{
|
||||
if ($resource = @sqlite_query($query, $handle)) {
|
||||
return $resource;
|
||||
public function query(
|
||||
string $query,
|
||||
$handle,
|
||||
int $op = Db::READ,
|
||||
?string $action = null,
|
||||
?string $table = null
|
||||
): \SQLite3Result {
|
||||
if ($stm = $handle->prepare($query)) {
|
||||
if ($resource = $stm->execute()) {
|
||||
return $resource;
|
||||
}
|
||||
}
|
||||
|
||||
/** 数据库异常 */
|
||||
$errorCode = sqlite_last_error($this->_dbHandle);
|
||||
throw new Typecho_Db_Query_Exception(sqlite_error_string($errorCode), $errorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象引号过滤
|
||||
*
|
||||
* @access public
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn($string)
|
||||
{
|
||||
return '"' . $string . '"';
|
||||
throw new SQLException($handle->lastErrorMsg(), $handle->lastErrorCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为对象取出,其中字段名对应对象属性
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @return object
|
||||
* @param \SQLite3Result $resource 查询的资源数据
|
||||
* @return object|null
|
||||
*/
|
||||
public function fetchObject($resource)
|
||||
public function fetchObject($resource): ?object
|
||||
{
|
||||
return (object)$this->fetch($resource);
|
||||
$result = $this->fetch($resource);
|
||||
return $result ? (object) $result : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的其中一行作为数组取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param resource $resource 查询返回资源标识
|
||||
* @param \SQLite3Result $resource 查询返回资源标识
|
||||
* @return array|null
|
||||
*/
|
||||
public function fetch($resource): ?array
|
||||
{
|
||||
$result = $resource->fetchArray(SQLITE3_ASSOC);
|
||||
return $result ? $this->filterColumnName($result) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据查询的结果作为数组全部取出,其中字段名对应数组键值
|
||||
*
|
||||
* @param \SQLite3Result $resource 查询的资源数据
|
||||
* @return array
|
||||
*/
|
||||
public function fetch($resource)
|
||||
public function fetchAll($resource): array
|
||||
{
|
||||
return Typecho_Common::filterSQLite2ColumnName(sqlite_fetch_array($resource, SQLITE_ASSOC));
|
||||
$result = [];
|
||||
|
||||
while ($row = $this->fetch($resource)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 引号转义函数
|
||||
*
|
||||
* @param string $string 需要转义的字符串
|
||||
* @param mixed $string 需要转义的字符串
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($string)
|
||||
public function quoteValue($string): string
|
||||
{
|
||||
return '\'' . str_replace('\'', '\'\'', $string) . '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
*/
|
||||
public function parseSelect(array $sql)
|
||||
{
|
||||
if (!empty($sql['join'])) {
|
||||
foreach ($sql['join'] as $val) {
|
||||
[$table, $condition, $op] = $val;
|
||||
$sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}";
|
||||
}
|
||||
}
|
||||
|
||||
$sql['limit'] = (0 == strlen($sql['limit'])) ? null : ' LIMIT ' . $sql['limit'];
|
||||
$sql['offset'] = (0 == strlen($sql['offset'])) ? null : ' OFFSET ' . $sql['offset'];
|
||||
|
||||
return Typecho_Common::filterSQLite2CountQuery('SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
|
||||
$sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次查询影响的行数
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @param \SQLite3Result $resource 查询的资源数据
|
||||
* @param \SQLite3 $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function affectedRows($resource, $handle)
|
||||
public function affectedRows($resource, $handle): int
|
||||
{
|
||||
return sqlite_changes($handle);
|
||||
return $handle->changes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出最后一次插入返回的主键值
|
||||
*
|
||||
* @param resource $resource 查询的资源数据
|
||||
* @param mixed $handle 连接对象
|
||||
* @param \SQLite3Result $resource 查询的资源数据
|
||||
* @param \SQLite3 $handle 连接对象
|
||||
* @return integer
|
||||
*/
|
||||
public function lastInsertId($resource, $handle)
|
||||
public function lastInsertId($resource, $handle): int
|
||||
{
|
||||
return sqlite_last_insert_rowid($handle);
|
||||
return $handle->lastInsertRowID();
|
||||
}
|
||||
}
|
||||
|
102
var/Typecho/Db/Adapter/SQLiteTrait.php
Normal file
102
var/Typecho/Db/Adapter/SQLiteTrait.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Typecho\Db\Adapter;
|
||||
|
||||
/**
|
||||
* SQLite Special Util
|
||||
*/
|
||||
trait SQLiteTrait
|
||||
{
|
||||
use QueryTrait;
|
||||
|
||||
private $isSQLite2 = false;
|
||||
|
||||
/**
|
||||
* 清空数据表
|
||||
*
|
||||
* @param string $table
|
||||
* @param mixed $handle 连接对象
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function truncate(string $table, $handle)
|
||||
{
|
||||
$this->query('DELETE FROM ' . $this->quoteColumn($table), $handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象引号过滤
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumn(string $string): string
|
||||
{
|
||||
return '"' . $string . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤字段名
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param array $result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterColumnName(array $result): array
|
||||
{
|
||||
/** 如果结果为空,直接返回 */
|
||||
if (empty($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$tResult = [];
|
||||
|
||||
/** 遍历数组 */
|
||||
foreach ($result as $key => $val) {
|
||||
/** 按点分隔 */
|
||||
if (false !== ($pos = strpos($key, '.'))) {
|
||||
$key = substr($key, $pos + 1);
|
||||
}
|
||||
|
||||
$tResult[trim($key, '"')] = $val;
|
||||
}
|
||||
|
||||
return $tResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理sqlite2的distinct count
|
||||
*
|
||||
* @param string $sql
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function filterCountQuery(string $sql): string
|
||||
{
|
||||
if (preg_match("/SELECT\s+COUNT\(DISTINCT\s+([^\)]+)\)\s+(AS\s+[^\s]+)?\s*FROM\s+(.+)/is", $sql, $matches)) {
|
||||
return 'SELECT COUNT(' . $matches[1] . ') ' . $matches[2] . ' FROM SELECT DISTINCT '
|
||||
. $matches[1] . ' FROM ' . $matches[3];
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成查询语句
|
||||
*
|
||||
* @access public
|
||||
* @param array $sql 查询对象词法数组
|
||||
* @return string
|
||||
*/
|
||||
public function parseSelect(array $sql): string
|
||||
{
|
||||
$query = $this->filterCountQuery($this->buildQuery($sql));
|
||||
|
||||
if ($this->isSQLite2) {
|
||||
$query = $this->filterCountQuery($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
@ -1,17 +1,18 @@
|
||||
<?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: DbException.php 52 2008-03-18 08:04:01Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho\Db;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use Typecho\Exception as TypechoException;
|
||||
|
||||
/**
|
||||
* 数据库异常类
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Exception extends Typecho_Exception
|
||||
{}
|
||||
class Exception extends TypechoException
|
||||
{
|
||||
}
|
||||
|
@ -1,16 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Typecho Blog Platform
|
||||
*
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id: DbQuery.php 97 2008-04-04 04:39:54Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho\Db;
|
||||
|
||||
use Typecho\Db;
|
||||
|
||||
/**
|
||||
* Typecho数据库查询语句构建类
|
||||
* 使用方法:
|
||||
* $query = new Typecho_Db_Query(); //或者使用DB积累的sql方法返回实例化对象
|
||||
* $query = new Query(); //或者使用DB积累的sql方法返回实例化对象
|
||||
* $query->select('posts', 'post_id, post_title')
|
||||
* ->where('post_id = %d', 1)
|
||||
* ->limit(1);
|
||||
@ -21,10 +18,10 @@
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Query
|
||||
class Query
|
||||
{
|
||||
/** 数据库关键字 */
|
||||
const KEYWORDS = '*PRIMARY|AND|OR|LIKE|BINARY|BY|DISTINCT|AS|IN|IS|NULL';
|
||||
private const KEYWORDS = '*PRIMARY|AND|OR|LIKE|BINARY|BY|DISTINCT|AS|IN|IS|NULL';
|
||||
|
||||
/**
|
||||
* 默认字段
|
||||
@ -32,7 +29,7 @@ class Typecho_Db_Query
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
private static $_default = [
|
||||
private static $default = [
|
||||
'action' => null,
|
||||
'table' => null,
|
||||
'fields' => '*',
|
||||
@ -49,16 +46,16 @@ class Typecho_Db_Query
|
||||
/**
|
||||
* 数据库适配器
|
||||
*
|
||||
* @var Typecho_Db_Adapter
|
||||
* @var Adapter
|
||||
*/
|
||||
private $_adapter;
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
* 查询语句预结构,由数组构成,方便组合为SQL查询字符串
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_sqlPreBuild;
|
||||
private $sqlPreBuild;
|
||||
|
||||
/**
|
||||
* 前缀
|
||||
@ -66,25 +63,25 @@ class Typecho_Db_Query
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_prefix;
|
||||
private $prefix;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_params = [];
|
||||
private $params = [];
|
||||
|
||||
/**
|
||||
* 构造函数,引用数据库适配器作为内部数据
|
||||
*
|
||||
* @param Typecho_Db_Adapter $adapter 数据库适配器
|
||||
* @param Adapter $adapter 数据库适配器
|
||||
* @param string $prefix 前缀
|
||||
*/
|
||||
public function __construct(Typecho_Db_Adapter $adapter, $prefix)
|
||||
public function __construct(Adapter $adapter, string $prefix)
|
||||
{
|
||||
$this->_adapter = &$adapter;
|
||||
$this->_prefix = $prefix;
|
||||
$this->adapter = &$adapter;
|
||||
$this->prefix = $prefix;
|
||||
|
||||
$this->_sqlPreBuild = self::$_default;
|
||||
$this->sqlPreBuild = self::$default;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,7 +91,7 @@ class Typecho_Db_Query
|
||||
*/
|
||||
public static function setDefault(array $default)
|
||||
{
|
||||
self::$_default = array_merge(self::$_default, $default);
|
||||
self::$default = array_merge(self::$default, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,9 +99,9 @@ class Typecho_Db_Query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getParams()
|
||||
public function getParams(): array
|
||||
{
|
||||
return $this->_params;
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,9 +111,9 @@ class Typecho_Db_Query
|
||||
* @param string $attributeName 属性名称
|
||||
* @return string
|
||||
*/
|
||||
public function getAttribute($attributeName)
|
||||
public function getAttribute(string $attributeName): ?string
|
||||
{
|
||||
return $this->_sqlPreBuild[$attributeName] ?? null;
|
||||
return $this->sqlPreBuild[$attributeName] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,12 +121,12 @@ class Typecho_Db_Query
|
||||
*
|
||||
* @access public
|
||||
* @param string $attributeName 属性名称
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function cleanAttribute($attributeName)
|
||||
public function cleanAttribute(string $attributeName): Query
|
||||
{
|
||||
if (isset($this->_sqlPreBuild[$attributeName])) {
|
||||
$this->_sqlPreBuild[$attributeName] = self::$_default[$attributeName];
|
||||
if (isset($this->sqlPreBuild[$attributeName])) {
|
||||
$this->sqlPreBuild[$attributeName] = self::$default[$attributeName];
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@ -140,11 +137,11 @@ class Typecho_Db_Query
|
||||
* @param string $table 需要连接的表
|
||||
* @param string $condition 连接条件
|
||||
* @param string $op 连接方法(LEFT, RIGHT, INNER)
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function join($table, $condition, $op = Typecho_Db::INNER_JOIN)
|
||||
public function join(string $table, string $condition, string $op = Db::INNER_JOIN): Query
|
||||
{
|
||||
$this->_sqlPreBuild['join'][] = [$this->filterPrefix($table), $this->filterColumn($condition), $op];
|
||||
$this->sqlPreBuild['join'][] = [$this->filterPrefix($table), $this->filterColumn($condition), $op];
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -154,9 +151,9 @@ class Typecho_Db_Query
|
||||
* @param string $string 需要解析的字符串
|
||||
* @return string
|
||||
*/
|
||||
private function filterPrefix($string)
|
||||
private function filterPrefix(string $string): string
|
||||
{
|
||||
return (0 === strpos($string, 'table.')) ? substr_replace($string, $this->_prefix, 0, 6) : $string;
|
||||
return (0 === strpos($string, 'table.')) ? substr_replace($string, $this->prefix, 0, 6) : $string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,7 +163,7 @@ class Typecho_Db_Query
|
||||
* @param string $str 待处理字段值
|
||||
* @return string
|
||||
*/
|
||||
private function filterColumn($str)
|
||||
private function filterColumn(string $str): string
|
||||
{
|
||||
$str = $str . ' 0';
|
||||
$length = strlen($str);
|
||||
@ -176,16 +173,18 @@ class Typecho_Db_Query
|
||||
$split = '';
|
||||
$quotes = 0;
|
||||
|
||||
for ($i = 0; $i < $length; $i ++) {
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$cha = $str[$i];
|
||||
|
||||
if (ctype_alnum($cha) || false !== strpos('_*', $cha)) {
|
||||
if (!$lastIsAlnum) {
|
||||
if ($quotes > 0 && !ctype_digit($word) && '.' != $split
|
||||
&& false === strpos(self::KEYWORDS, strtoupper($word))) {
|
||||
$word = $this->_adapter->quoteColumn($word);
|
||||
if (
|
||||
$quotes > 0 && !ctype_digit($word) && '.' != $split
|
||||
&& false === strpos(self::KEYWORDS, strtoupper($word))
|
||||
) {
|
||||
$word = $this->adapter->quoteColumn($word);
|
||||
} elseif ('.' == $split && 'table' == $word) {
|
||||
$word = $this->_prefix;
|
||||
$word = $this->prefix;
|
||||
$split = '';
|
||||
}
|
||||
|
||||
@ -197,9 +196,7 @@ class Typecho_Db_Query
|
||||
$word .= $cha;
|
||||
$lastIsAlnum = true;
|
||||
} else {
|
||||
|
||||
if ($lastIsAlnum) {
|
||||
|
||||
if (0 == $quotes) {
|
||||
if (false !== strpos(' ,)=<>.+-*/', $cha)) {
|
||||
$quotes = 1;
|
||||
@ -226,17 +223,17 @@ class Typecho_Db_Query
|
||||
* @param ...$args
|
||||
* @return $this
|
||||
*/
|
||||
public function where(...$args)
|
||||
public function where(...$args): Query
|
||||
{
|
||||
[$condition] = $args;
|
||||
$condition = str_replace('?', "%s", $this->filterColumn($condition));
|
||||
$operator = empty($this->_sqlPreBuild['where']) ? ' WHERE ' : ' AND';
|
||||
$operator = empty($this->sqlPreBuild['where']) ? ' WHERE ' : ' AND';
|
||||
|
||||
if (count($args) <= 1) {
|
||||
$this->_sqlPreBuild['where'] .= $operator . ' (' . $condition . ')';
|
||||
$this->sqlPreBuild['where'] .= $operator . ' (' . $condition . ')';
|
||||
} else {
|
||||
array_shift($args);
|
||||
$this->_sqlPreBuild['where'] .= $operator . ' (' . vsprintf($condition, $this->quoteValues($args)) . ')';
|
||||
$this->sqlPreBuild['where'] .= $operator . ' (' . vsprintf($condition, $this->quoteValues($args)) . ')';
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -249,7 +246,7 @@ class Typecho_Db_Query
|
||||
* @access protected
|
||||
* @return array
|
||||
*/
|
||||
protected function quoteValues(array $values)
|
||||
protected function quoteValues(array $values): array
|
||||
{
|
||||
foreach ($values as &$value) {
|
||||
if (is_array($value)) {
|
||||
@ -268,29 +265,29 @@ class Typecho_Db_Query
|
||||
* @param $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteValue($value)
|
||||
public function quoteValue($value): string
|
||||
{
|
||||
$this->_params[] = $value;
|
||||
return '#param:' . (count($this->_params) - 1) . '#';
|
||||
$this->params[] = $value;
|
||||
return '#param:' . (count($this->params) - 1) . '#';
|
||||
}
|
||||
|
||||
/**
|
||||
* OR条件查询语句
|
||||
*
|
||||
* @param ...$args
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function orWhere(...$args)
|
||||
public function orWhere(...$args): Query
|
||||
{
|
||||
[$condition] = $args;
|
||||
$condition = str_replace('?', "%s", $this->filterColumn($condition));
|
||||
$operator = empty($this->_sqlPreBuild['where']) ? ' WHERE ' : ' OR';
|
||||
$operator = empty($this->sqlPreBuild['where']) ? ' WHERE ' : ' OR';
|
||||
|
||||
if (func_num_args() <= 1) {
|
||||
$this->_sqlPreBuild['where'] .= $operator . ' (' . $condition . ')';
|
||||
$this->sqlPreBuild['where'] .= $operator . ' (' . $condition . ')';
|
||||
} else {
|
||||
array_shift($args);
|
||||
$this->_sqlPreBuild['where'] .= $operator . ' (' . vsprintf($condition, $this->quoteValues($args)) . ')';
|
||||
$this->sqlPreBuild['where'] .= $operator . ' (' . vsprintf($condition, $this->quoteValues($args)) . ')';
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -299,39 +296,39 @@ class Typecho_Db_Query
|
||||
/**
|
||||
* 查询行数限制
|
||||
*
|
||||
* @param integer $limit 需要查询的行数
|
||||
* @return Typecho_Db_Query
|
||||
* @param mixed $limit 需要查询的行数
|
||||
* @return Query
|
||||
*/
|
||||
public function limit($limit)
|
||||
public function limit($limit): Query
|
||||
{
|
||||
$this->_sqlPreBuild['limit'] = intval($limit);
|
||||
$this->sqlPreBuild['limit'] = intval($limit);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询行数偏移量
|
||||
*
|
||||
* @param integer $offset 需要偏移的行数
|
||||
* @return Typecho_Db_Query
|
||||
* @param mixed $offset 需要偏移的行数
|
||||
* @return Query
|
||||
*/
|
||||
public function offset($offset)
|
||||
public function offset($offset): Query
|
||||
{
|
||||
$this->_sqlPreBuild['offset'] = intval($offset);
|
||||
$this->sqlPreBuild['offset'] = intval($offset);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param integer $page 页数
|
||||
* @param integer $pageSize 每页行数
|
||||
* @return Typecho_Db_Query
|
||||
* @param mixed $page 页数
|
||||
* @param mixed $pageSize 每页行数
|
||||
* @return Query
|
||||
*/
|
||||
public function page($page, $pageSize)
|
||||
public function page($page, $pageSize): Query
|
||||
{
|
||||
$pageSize = intval($pageSize);
|
||||
$this->_sqlPreBuild['limit'] = $pageSize;
|
||||
$this->_sqlPreBuild['offset'] = (max(intval($page), 1) - 1) * $pageSize;
|
||||
$this->sqlPreBuild['limit'] = $pageSize;
|
||||
$this->sqlPreBuild['offset'] = (max(intval($page), 1) - 1) * $pageSize;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -339,12 +336,13 @@ class Typecho_Db_Query
|
||||
* 指定需要写入的栏目及其值
|
||||
*
|
||||
* @param array $rows
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function rows(array $rows)
|
||||
public function rows(array $rows): Query
|
||||
{
|
||||
foreach ($rows as $key => $row) {
|
||||
$this->_sqlPreBuild['rows'][$this->filterColumn($key)] = is_null($row) ? 'NULL' : $this->_adapter->quoteValue($row);
|
||||
$this->sqlPreBuild['rows'][$this->filterColumn($key)]
|
||||
= is_null($row) ? 'NULL' : $this->adapter->quoteValue($row);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@ -356,30 +354,30 @@ class Typecho_Db_Query
|
||||
* @param string $key 栏目名称
|
||||
* @param mixed $value 指定的值
|
||||
* @param bool $escape 是否转义
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function expression($key, $value, $escape = true)
|
||||
public function expression(string $key, $value, bool $escape = true): Query
|
||||
{
|
||||
$this->_sqlPreBuild['rows'][$this->filterColumn($key)] = $escape ? $this->filterColumn($value) : $value;
|
||||
$this->sqlPreBuild['rows'][$this->filterColumn($key)] = $escape ? $this->filterColumn($value) : $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 排序顺序(ORDER BY)
|
||||
*
|
||||
* @param string $orderby 排序的索引
|
||||
* @param string $orderBy 排序的索引
|
||||
* @param string $sort 排序的方式(ASC, DESC)
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function order($orderby, $sort = Typecho_Db::SORT_ASC)
|
||||
public function order(string $orderBy, string $sort = Db::SORT_ASC): Query
|
||||
{
|
||||
if (empty($this->_sqlPreBuild['order'])) {
|
||||
$this->_sqlPreBuild['order'] = ' ORDER BY ';
|
||||
if (empty($this->sqlPreBuild['order'])) {
|
||||
$this->sqlPreBuild['order'] = ' ORDER BY ';
|
||||
} else {
|
||||
$this->_sqlPreBuild['order'] .= ', ';
|
||||
$this->sqlPreBuild['order'] .= ', ';
|
||||
}
|
||||
|
||||
$this->_sqlPreBuild['order'] .= $this->filterColumn($orderby) . (empty($sort) ? null : ' ' . $sort);
|
||||
$this->sqlPreBuild['order'] .= $this->filterColumn($orderBy) . (empty($sort) ? null : ' ' . $sort);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -387,31 +385,28 @@ class Typecho_Db_Query
|
||||
* 集合聚集(GROUP BY)
|
||||
*
|
||||
* @param string $key 聚集的键值
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function group($key)
|
||||
public function group(string $key): Query
|
||||
{
|
||||
$this->_sqlPreBuild['group'] = ' GROUP BY ' . $this->filterColumn($key);
|
||||
$this->sqlPreBuild['group'] = ' GROUP BY ' . $this->filterColumn($key);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* HAVING (HAVING)
|
||||
*
|
||||
* @return Typecho_Db_Query
|
||||
* @param string $condition
|
||||
* @param ...$args
|
||||
* @return $this
|
||||
*/
|
||||
public function having()
|
||||
public function having(string $condition, ...$args): Query
|
||||
{
|
||||
$condition = func_get_arg(0);
|
||||
$condition = str_replace('?', "%s", $this->filterColumn($condition));
|
||||
$operator = empty($this->_sqlPreBuild['having']) ? ' HAVING ' : ' AND';
|
||||
$operator = empty($this->sqlPreBuild['having']) ? ' HAVING ' : ' AND';
|
||||
|
||||
if (func_num_args() <= 1) {
|
||||
$this->_sqlPreBuild['having'] .= $operator . ' (' . $condition . ')';
|
||||
if (count($args) == 0) {
|
||||
$this->sqlPreBuild['having'] .= $operator . ' (' . $condition . ')';
|
||||
} else {
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
$this->_sqlPreBuild['having'] .= $operator . ' (' . vsprintf($condition, $this->quoteValues($args)) . ')';
|
||||
$this->sqlPreBuild['having'] .= $operator . ' (' . vsprintf($condition, $this->quoteValues($args)) . ')';
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -423,11 +418,11 @@ class Typecho_Db_Query
|
||||
* @param mixed ...$args 查询字段
|
||||
* @return $this
|
||||
*/
|
||||
public function select(...$args): Typecho_Db_Query
|
||||
public function select(...$args): Query
|
||||
{
|
||||
$this->_sqlPreBuild['action'] = Typecho_Db::SELECT;
|
||||
$this->sqlPreBuild['action'] = Db::SELECT;
|
||||
|
||||
$this->_sqlPreBuild['fields'] = $this->getColumnFromParameters($args);
|
||||
$this->sqlPreBuild['fields'] = $this->getColumnFromParameters($args);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -438,7 +433,7 @@ class Typecho_Db_Query
|
||||
* @param array $parameters
|
||||
* @return string
|
||||
*/
|
||||
private function getColumnFromParameters(array $parameters)
|
||||
private function getColumnFromParameters(array $parameters): string
|
||||
{
|
||||
$fields = [];
|
||||
|
||||
@ -459,11 +454,11 @@ class Typecho_Db_Query
|
||||
* 查询记录操作(SELECT)
|
||||
*
|
||||
* @param string $table 查询的表
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function from($table)
|
||||
public function from(string $table): Query
|
||||
{
|
||||
$this->_sqlPreBuild['table'] = $this->filterPrefix($table);
|
||||
$this->sqlPreBuild['table'] = $this->filterPrefix($table);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -471,12 +466,12 @@ class Typecho_Db_Query
|
||||
* 更新记录操作(UPDATE)
|
||||
*
|
||||
* @param string $table 需要更新记录的表
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function update($table)
|
||||
public function update(string $table): Query
|
||||
{
|
||||
$this->_sqlPreBuild['action'] = Typecho_Db::UPDATE;
|
||||
$this->_sqlPreBuild['table'] = $this->filterPrefix($table);
|
||||
$this->sqlPreBuild['action'] = Db::UPDATE;
|
||||
$this->sqlPreBuild['table'] = $this->filterPrefix($table);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -484,12 +479,12 @@ class Typecho_Db_Query
|
||||
* 删除记录操作(DELETE)
|
||||
*
|
||||
* @param string $table 需要删除记录的表
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function delete($table)
|
||||
public function delete(string $table): Query
|
||||
{
|
||||
$this->_sqlPreBuild['action'] = Typecho_Db::DELETE;
|
||||
$this->_sqlPreBuild['table'] = $this->filterPrefix($table);
|
||||
$this->sqlPreBuild['action'] = Db::DELETE;
|
||||
$this->sqlPreBuild['table'] = $this->filterPrefix($table);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -497,23 +492,23 @@ class Typecho_Db_Query
|
||||
* 插入记录操作(INSERT)
|
||||
*
|
||||
* @param string $table 需要插入记录的表
|
||||
* @return Typecho_Db_Query
|
||||
* @return Query
|
||||
*/
|
||||
public function insert($table)
|
||||
public function insert(string $table): Query
|
||||
{
|
||||
$this->_sqlPreBuild['action'] = Typecho_Db::INSERT;
|
||||
$this->_sqlPreBuild['table'] = $this->filterPrefix($table);
|
||||
$this->sqlPreBuild['action'] = Db::INSERT;
|
||||
$this->sqlPreBuild['table'] = $this->filterPrefix($table);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param string $query
|
||||
* @return string
|
||||
*/
|
||||
public function prepare($query)
|
||||
public function prepare(string $query): string
|
||||
{
|
||||
$params = $this->_params;
|
||||
$adapter = $this->_adapter;
|
||||
$params = $this->params;
|
||||
$adapter = $this->adapter;
|
||||
|
||||
return preg_replace_callback("/#param:([0-9]+)#/", function ($matches) use ($params, $adapter) {
|
||||
if (array_key_exists($matches[1], $params)) {
|
||||
@ -531,32 +526,32 @@ class Typecho_Db_Query
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
switch ($this->_sqlPreBuild['action']) {
|
||||
case Typecho_Db::SELECT:
|
||||
return $this->_adapter->parseSelect($this->_sqlPreBuild);
|
||||
case Typecho_Db::INSERT:
|
||||
switch ($this->sqlPreBuild['action']) {
|
||||
case Db::SELECT:
|
||||
return $this->adapter->parseSelect($this->sqlPreBuild);
|
||||
case Db::INSERT:
|
||||
return 'INSERT INTO '
|
||||
. $this->_sqlPreBuild['table']
|
||||
. '(' . implode(' , ', array_keys($this->_sqlPreBuild['rows'])) . ')'
|
||||
. $this->sqlPreBuild['table']
|
||||
. '(' . implode(' , ', array_keys($this->sqlPreBuild['rows'])) . ')'
|
||||
. ' VALUES '
|
||||
. '(' . implode(' , ', array_values($this->_sqlPreBuild['rows'])) . ')'
|
||||
. $this->_sqlPreBuild['limit'];
|
||||
case Typecho_Db::DELETE:
|
||||
. '(' . implode(' , ', array_values($this->sqlPreBuild['rows'])) . ')'
|
||||
. $this->sqlPreBuild['limit'];
|
||||
case Db::DELETE:
|
||||
return 'DELETE FROM '
|
||||
. $this->_sqlPreBuild['table']
|
||||
. $this->_sqlPreBuild['where'];
|
||||
case Typecho_Db::UPDATE:
|
||||
. $this->sqlPreBuild['table']
|
||||
. $this->sqlPreBuild['where'];
|
||||
case Db::UPDATE:
|
||||
$columns = [];
|
||||
if (isset($this->_sqlPreBuild['rows'])) {
|
||||
foreach ($this->_sqlPreBuild['rows'] as $key => $val) {
|
||||
if (isset($this->sqlPreBuild['rows'])) {
|
||||
foreach ($this->sqlPreBuild['rows'] as $key => $val) {
|
||||
$columns[] = "$key = $val";
|
||||
}
|
||||
}
|
||||
|
||||
return 'UPDATE '
|
||||
. $this->_sqlPreBuild['table']
|
||||
. $this->sqlPreBuild['table']
|
||||
. ' SET ' . implode(' , ', $columns)
|
||||
. $this->_sqlPreBuild['where'];
|
||||
. $this->sqlPreBuild['where'];
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -1,17 +1,18 @@
|
||||
<?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: DbException.php 52 2008-03-18 08:04:01Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho\Db\Query;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use Typecho\Db\Exception as DbException;
|
||||
|
||||
/**
|
||||
* 数据库查询异常类
|
||||
*
|
||||
* @package Db
|
||||
*/
|
||||
class Typecho_Db_Query_Exception extends Typecho_Db_Exception
|
||||
{}
|
||||
class Exception extends DbException
|
||||
{
|
||||
}
|
||||
|
@ -1,11 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Typecho Blog Platform
|
||||
*
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id: Exception.php 106 2008-04-11 02:23:54Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho;
|
||||
|
||||
/**
|
||||
* Typecho异常基类
|
||||
@ -13,7 +8,7 @@
|
||||
*
|
||||
* @package Exception
|
||||
*/
|
||||
class Typecho_Exception extends Exception
|
||||
class Exception extends \Exception
|
||||
{
|
||||
|
||||
public function __construct($message, $code = 0)
|
||||
|
@ -1,43 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* 格式化聚合XML数据,整合自Univarsel Feed Writer
|
||||
*
|
||||
* @author Anis uddin Ahmad <anisniit@gmail.com>
|
||||
* @category typecho
|
||||
* @package Feed
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id: Feed.php 219 2008-05-27 09:06:15Z magike.net $
|
||||
*/
|
||||
|
||||
namespace Typecho;
|
||||
|
||||
/**
|
||||
* Typecho_Feed
|
||||
* Feed
|
||||
*
|
||||
* @author qining
|
||||
* @category typecho
|
||||
* @package Feed
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
*/
|
||||
class Typecho_Feed
|
||||
class Feed
|
||||
{
|
||||
/** 定义RSS 1.0类型 */
|
||||
const RSS1 = 'RSS 1.0';
|
||||
public const RSS1 = 'RSS 1.0';
|
||||
|
||||
/** 定义RSS 2.0类型 */
|
||||
const RSS2 = 'RSS 2.0';
|
||||
public const RSS2 = 'RSS 2.0';
|
||||
|
||||
/** 定义ATOM 1.0类型 */
|
||||
const ATOM1 = 'ATOM 1.0';
|
||||
public const ATOM1 = 'ATOM 1.0';
|
||||
|
||||
/** 定义RSS时间格式 */
|
||||
const DATE_RFC822 = 'r';
|
||||
public const DATE_RFC822 = 'r';
|
||||
|
||||
/** 定义ATOM时间格式 */
|
||||
const DATE_W3CDTF = 'c';
|
||||
public const DATE_W3CDTF = 'c';
|
||||
|
||||
/** 定义行结束符 */
|
||||
const EOL = "\n";
|
||||
public const EOL = "\n";
|
||||
|
||||
/**
|
||||
* feed状态
|
||||
@ -45,7 +33,7 @@ class Typecho_Feed
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_type;
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* 字符集编码
|
||||
@ -53,7 +41,7 @@ class Typecho_Feed
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_charset;
|
||||
private $charset;
|
||||
|
||||
/**
|
||||
* 语言状态
|
||||
@ -61,7 +49,7 @@ class Typecho_Feed
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_lang;
|
||||
private $lang;
|
||||
|
||||
/**
|
||||
* 聚合地址
|
||||
@ -69,7 +57,7 @@ class Typecho_Feed
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_feedUrl;
|
||||
private $feedUrl;
|
||||
|
||||
/**
|
||||
* 基本地址
|
||||
@ -77,7 +65,7 @@ class Typecho_Feed
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_baseUrl;
|
||||
private $baseUrl;
|
||||
|
||||
/**
|
||||
* 聚合标题
|
||||
@ -85,7 +73,7 @@ class Typecho_Feed
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_title;
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* 聚合副标题
|
||||
@ -93,7 +81,7 @@ class Typecho_Feed
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_subTitle;
|
||||
private $subTitle;
|
||||
|
||||
/**
|
||||
* 版本信息
|
||||
@ -101,7 +89,7 @@ class Typecho_Feed
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_version;
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* 所有的items
|
||||
@ -109,76 +97,62 @@ class Typecho_Feed
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $_items = [];
|
||||
private $items = [];
|
||||
|
||||
/**
|
||||
* 创建Feed对象
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @param $version
|
||||
* @param string $type
|
||||
* @param string $charset
|
||||
* @param string $lang
|
||||
*/
|
||||
public function __construct($version, $type = self::RSS2, $charset = 'UTF-8', $lang = 'en')
|
||||
public function __construct($version, string $type = self::RSS2, string $charset = 'UTF-8', string $lang = 'en')
|
||||
{
|
||||
$this->_version = $version;
|
||||
$this->_type = $type;
|
||||
$this->_charset = $charset;
|
||||
$this->_lang = $lang;
|
||||
$this->version = $version;
|
||||
$this->type = $type;
|
||||
$this->charset = $charset;
|
||||
$this->lang = $lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $title 标题
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTitle(string $title)
|
||||
{
|
||||
$this->_title = $title;
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置副标题
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $subTitle 副标题
|
||||
*
|
||||
* @return void
|
||||
* @param string|null $subTitle 副标题
|
||||
*/
|
||||
public function setSubTitle(string $subTitle)
|
||||
public function setSubTitle(?string $subTitle)
|
||||
{
|
||||
$this->_subTitle = $subTitle;
|
||||
$this->subTitle = $subTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置聚合地址
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $feedUrl 聚合地址
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFeedUrl(string $feedUrl)
|
||||
{
|
||||
$this->_feedUrl = $feedUrl;
|
||||
$this->feedUrl = $feedUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置主页
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $baseUrl 主页地址
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setBaseUrl(string $baseUrl)
|
||||
{
|
||||
$this->_baseUrl = $baseUrl;
|
||||
$this->baseUrl = $baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,26 +171,23 @@ class Typecho_Feed
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array $item
|
||||
*/
|
||||
public function addItem(array $item)
|
||||
{
|
||||
$this->_items[] = $item;
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出字符串
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
$result = '<?xml version="1.0" encoding="' . $this->_charset . '"?>' . self::EOL;
|
||||
$result = '<?xml version="1.0" encoding="' . $this->charset . '"?>' . self::EOL;
|
||||
|
||||
if (self::RSS1 == $this->_type) {
|
||||
if (self::RSS1 == $this->type) {
|
||||
$result .= '<rdf:RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
@ -226,7 +197,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/">' . self::EOL;
|
||||
$links = [];
|
||||
$lastUpdate = 0;
|
||||
|
||||
foreach ($this->_items as $item) {
|
||||
foreach ($this->items as $item) {
|
||||
$content .= '<item rdf:about="' . $item['link'] . '">' . self::EOL;
|
||||
$content .= '<title>' . htmlspecialchars($item['title']) . '</title>' . self::EOL;
|
||||
$content .= '<link>' . $item['link'] . '</link>' . self::EOL;
|
||||
@ -244,10 +215,10 @@ xmlns:dc="http://purl.org/dc/elements/1.1/">' . self::EOL;
|
||||
}
|
||||
}
|
||||
|
||||
$result .= '<channel rdf:about="' . $this->_feedUrl . '">
|
||||
<title>' . htmlspecialchars($this->_title) . '</title>
|
||||
<link>' . $this->_baseUrl . '</link>
|
||||
<description>' . htmlspecialchars($this->_subTitle) . '</description>
|
||||
$result .= '<channel rdf:about="' . $this->feedUrl . '">
|
||||
<title>' . htmlspecialchars($this->title) . '</title>
|
||||
<link>' . $this->baseUrl . '</link>
|
||||
<description>' . htmlspecialchars($this->subTitle) . '</description>
|
||||
<items>
|
||||
<rdf:Seq>' . self::EOL;
|
||||
|
||||
@ -260,8 +231,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/">' . self::EOL;
|
||||
</channel>' . self::EOL;
|
||||
|
||||
$result .= $content . '</rdf:RDF>';
|
||||
|
||||
} else if (self::RSS2 == $this->_type) {
|
||||
} elseif (self::RSS2 == $this->type) {
|
||||
$result .= '<rss version="2.0"
|
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
@ -273,13 +243,14 @@ xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
$content = '';
|
||||
$lastUpdate = 0;
|
||||
|
||||
foreach ($this->_items as $item) {
|
||||
foreach ($this->items as $item) {
|
||||
$content .= '<item>' . self::EOL;
|
||||
$content .= '<title>' . htmlspecialchars($item['title']) . '</title>' . self::EOL;
|
||||
$content .= '<link>' . $item['link'] . '</link>' . self::EOL;
|
||||
$content .= '<guid>' . $item['link'] . '</guid>' . self::EOL;
|
||||
$content .= '<pubDate>' . $this->dateFormat($item['date']) . '</pubDate>' . self::EOL;
|
||||
$content .= '<dc:creator>' . htmlspecialchars($item['author']->screenName) . '</dc:creator>' . self::EOL;
|
||||
$content .= '<dc:creator>' . htmlspecialchars($item['author']->screenName)
|
||||
. '</dc:creator>' . self::EOL;
|
||||
|
||||
if (!empty($item['category']) && is_array($item['category'])) {
|
||||
foreach ($item['category'] as $category) {
|
||||
@ -288,11 +259,12 @@ xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
}
|
||||
|
||||
if (!empty($item['excerpt'])) {
|
||||
$content .= '<description><![CDATA[' . strip_tags($item['excerpt']) . ']]></description>' . self::EOL;
|
||||
$content .= '<description><![CDATA[' . strip_tags($item['excerpt'])
|
||||
. ']]></description>' . self::EOL;
|
||||
}
|
||||
|
||||
if (!empty($item['content'])) {
|
||||
$content .= '<content:encoded xml:lang="' . $this->_lang . '"><![CDATA['
|
||||
$content .= '<content:encoded xml:lang="' . $this->lang . '"><![CDATA['
|
||||
. self::EOL .
|
||||
$item['content'] . self::EOL .
|
||||
']]></content:encoded>' . self::EOL;
|
||||
@ -318,28 +290,27 @@ xmlns:wfw="http://wellformedweb.org/CommentAPI/">
|
||||
}
|
||||
}
|
||||
|
||||
$result .= '<title>' . htmlspecialchars($this->_title) . '</title>
|
||||
<link>' . $this->_baseUrl . '</link>
|
||||
<atom:link href="' . $this->_feedUrl . '" rel="self" type="application/rss+xml" />
|
||||
<language>' . $this->_lang . '</language>
|
||||
<description>' . htmlspecialchars($this->_subTitle) . '</description>
|
||||
$result .= '<title>' . htmlspecialchars($this->title) . '</title>
|
||||
<link>' . $this->baseUrl . '</link>
|
||||
<atom:link href="' . $this->feedUrl . '" rel="self" type="application/rss+xml" />
|
||||
<language>' . $this->lang . '</language>
|
||||
<description>' . htmlspecialchars($this->subTitle) . '</description>
|
||||
<lastBuildDate>' . $this->dateFormat($lastUpdate) . '</lastBuildDate>
|
||||
<pubDate>' . $this->dateFormat($lastUpdate) . '</pubDate>' . self::EOL;
|
||||
|
||||
$result .= $content . '</channel>
|
||||
</rss>';
|
||||
|
||||
} else if (self::ATOM1 == $this->_type) {
|
||||
} elseif (self::ATOM1 == $this->type) {
|
||||
$result .= '<feed xmlns="http://www.w3.org/2005/Atom"
|
||||
xmlns:thr="http://purl.org/syndication/thread/1.0"
|
||||
xml:lang="' . $this->_lang . '"
|
||||
xml:base="' . $this->_baseUrl . '"
|
||||
xml:lang="' . $this->lang . '"
|
||||
xml:base="' . $this->baseUrl . '"
|
||||
>' . self::EOL;
|
||||
|
||||
$content = '';
|
||||
$lastUpdate = 0;
|
||||
|
||||
foreach ($this->_items as $item) {
|
||||
foreach ($this->items as $item) {
|
||||
$content .= '<entry>' . self::EOL;
|
||||
$content .= '<title type="html"><![CDATA[' . $item['title'] . ']]></title>' . self::EOL;
|
||||
$content .= '<link rel="alternate" type="text/html" href="' . $item['link'] . '" />' . self::EOL;
|
||||
@ -353,26 +324,31 @@ xml:base="' . $this->_baseUrl . '"
|
||||
|
||||
if (!empty($item['category']) && is_array($item['category'])) {
|
||||
foreach ($item['category'] as $category) {
|
||||
$content .= '<category scheme="' . $category['permalink'] . '" term="' . $category['name'] . '" />' . self::EOL;
|
||||
$content .= '<category scheme="' . $category['permalink'] . '" term="'
|
||||
. $category['name'] . '" />' . self::EOL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($item['excerpt'])) {
|
||||
$content .= '<summary type="html"><![CDATA[' . htmlspecialchars($item['excerpt']) . ']]></summary>' . self::EOL;
|
||||
$content .= '<summary type="html"><![CDATA[' . htmlspecialchars($item['excerpt'])
|
||||
. ']]></summary>' . self::EOL;
|
||||
}
|
||||
|
||||
if (!empty($item['content'])) {
|
||||
$content .= '<content type="html" xml:base="' . $item['link'] . '" xml:lang="' . $this->_lang . '"><![CDATA['
|
||||
$content .= '<content type="html" xml:base="' . $item['link']
|
||||
. '" xml:lang="' . $this->lang . '"><![CDATA['
|
||||
. self::EOL .
|
||||
$item['content'] . self::EOL .
|
||||
']]></content>' . self::EOL;
|
||||
}
|
||||
|
||||
if (isset($item['comments']) && strlen($item['comments']) > 0) {
|
||||
$content .= '<link rel="replies" type="text/html" href="' . $item['link'] . '#comments" thr:count="' . $item['comments'] . '" />' . self::EOL;
|
||||
$content .= '<link rel="replies" type="text/html" href="' . $item['link']
|
||||
. '#comments" thr:count="' . $item['comments'] . '" />' . self::EOL;
|
||||
|
||||
if (!empty($item['commentsFeedUrl'])) {
|
||||
$content .= '<link rel="replies" type="application/atom+xml" href="' . $item['commentsFeedUrl'] . '" thr:count="' . $item['comments'] . '"/>' . self::EOL;
|
||||
$content .= '<link rel="replies" type="application/atom+xml" href="'
|
||||
. $item['commentsFeedUrl'] . '" thr:count="' . $item['comments'] . '"/>' . self::EOL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,13 +363,13 @@ xml:base="' . $this->_baseUrl . '"
|
||||
}
|
||||
}
|
||||
|
||||
$result .= '<title type="text">' . htmlspecialchars($this->_title) . '</title>
|
||||
<subtitle type="text">' . htmlspecialchars($this->_subTitle) . '</subtitle>
|
||||
$result .= '<title type="text">' . htmlspecialchars($this->title) . '</title>
|
||||
<subtitle type="text">' . htmlspecialchars($this->subTitle) . '</subtitle>
|
||||
<updated>' . $this->dateFormat($lastUpdate) . '</updated>
|
||||
<generator uri="http://typecho.org/" version="' . $this->_version . '">Typecho</generator>
|
||||
<link rel="alternate" type="text/html" href="' . $this->_baseUrl . '" />
|
||||
<id>' . $this->_feedUrl . '</id>
|
||||
<link rel="self" type="application/atom+xml" href="' . $this->_feedUrl . '" />
|
||||
<generator uri="http://typecho.org/" version="' . $this->version . '">Typecho</generator>
|
||||
<link rel="alternate" type="text/html" href="' . $this->baseUrl . '" />
|
||||
<id>' . $this->feedUrl . '</id>
|
||||
<link rel="self" type="application/atom+xml" href="' . $this->feedUrl . '" />
|
||||
';
|
||||
$result .= $content . '</feed>';
|
||||
}
|
||||
@ -404,18 +380,17 @@ xml:base="' . $this->_baseUrl . '"
|
||||
/**
|
||||
* 获取Feed时间格式
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param integer $stamp 时间戳
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dateFormat(int $stamp): string
|
||||
{
|
||||
if (self::RSS2 == $this->_type) {
|
||||
if (self::RSS2 == $this->type) {
|
||||
return date(self::DATE_RFC822, $stamp);
|
||||
} else if (self::RSS1 == $this->_type || self::ATOM1 == $this->_type) {
|
||||
} elseif (self::RSS1 == $this->type || self::ATOM1 == $this->type) {
|
||||
return date(self::DATE_W3CDTF, $stamp);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Http客户端
|
||||
*
|
||||
* @author qining
|
||||
* @category typecho
|
||||
* @package Http
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
namespace Typecho\Http;
|
||||
|
||||
use Typecho\Http\Client\Adapter;
|
||||
|
||||
/**
|
||||
* Http客户端
|
||||
@ -17,39 +11,29 @@
|
||||
* @category typecho
|
||||
* @package Http
|
||||
*/
|
||||
class Typecho_Http_Client
|
||||
class Client
|
||||
{
|
||||
/** POST方法 */
|
||||
const METHOD_POST = 'POST';
|
||||
public const METHOD_POST = 'POST';
|
||||
|
||||
/** GET方法 */
|
||||
const METHOD_GET = 'GET';
|
||||
public const METHOD_GET = 'GET';
|
||||
|
||||
/** 定义行结束符 */
|
||||
const EOL = "\r\n";
|
||||
public const EOL = "\r\n";
|
||||
|
||||
private const ADAPTERS = [Adapter\Curl::class, Adapter\Socket::class];
|
||||
|
||||
/**
|
||||
* 获取可用的连接
|
||||
*
|
||||
* @access public
|
||||
* @return ?Typecho_Http_Client_Adapter
|
||||
* @return ?Adapter
|
||||
*/
|
||||
public static function get(): ?Typecho_Http_Client_Adapter
|
||||
public static function get(): ?Adapter
|
||||
{
|
||||
$adapters = func_get_args();
|
||||
|
||||
if (empty($adapters)) {
|
||||
$adapters = [];
|
||||
$adapterFiles = glob(dirname(__FILE__) . '/Client/Adapter/*.php');
|
||||
foreach ($adapterFiles as $file) {
|
||||
$adapters[] = substr(basename($file), 0, - 4);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($adapters as $adapter) {
|
||||
$adapterName = 'Typecho_Http_Client_Adapter_' . $adapter;
|
||||
if (Typecho_Common::isAvailableClass($adapterName) && call_user_func([$adapterName, 'isAvailable'])) {
|
||||
return new $adapterName();
|
||||
foreach (self::ADAPTERS as $adapter) {
|
||||
if (call_user_func([$adapter, 'isAvailable'])) {
|
||||
return new $adapter();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,9 @@
|
||||
<?php
|
||||
/**
|
||||
* 客户端适配器
|
||||
*
|
||||
* @author qining
|
||||
* @category typecho
|
||||
* @package Http
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
namespace Typecho\Http\Client;
|
||||
|
||||
use Typecho\Common;
|
||||
use Typecho\Http\Client;
|
||||
|
||||
/**
|
||||
* 客户端适配器
|
||||
@ -17,7 +12,7 @@
|
||||
* @category typecho
|
||||
* @package Http
|
||||
*/
|
||||
abstract class Typecho_Http_Client_Adapter
|
||||
abstract class Adapter
|
||||
{
|
||||
/**
|
||||
* 方法名
|
||||
@ -25,7 +20,7 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $method = Typecho_Http_Client::METHOD_GET;
|
||||
protected $method = Client::METHOD_GET;
|
||||
|
||||
/**
|
||||
* 传递参数
|
||||
@ -47,7 +42,7 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* 需要在body中传递的值
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
* @var array|string
|
||||
*/
|
||||
protected $data = [];
|
||||
|
||||
@ -161,10 +156,7 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
abstract public static function isAvailable(): bool;
|
||||
|
||||
/**
|
||||
* 设置指定的COOKIE值
|
||||
@ -172,9 +164,9 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* @access public
|
||||
* @param string $key 指定的参数
|
||||
* @param mixed $value 设置的值
|
||||
* @return Typecho_Http_Client_Adapter
|
||||
* @return $this
|
||||
*/
|
||||
public function setCookie($key, $value)
|
||||
public function setCookie(string $key, $value): Adapter
|
||||
{
|
||||
$this->cookies[$key] = $value;
|
||||
return $this;
|
||||
@ -185,9 +177,9 @@ abstract class Typecho_Http_Client_Adapter
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $query 传递参数
|
||||
* @return Typecho_Http_Client_Adapter
|
||||
* @return $this
|
||||
*/
|
||||
public function setQuery($query)
|
||||
public function setQuery($query): Adapter
|
||||
{
|
||||
$query = is_array($query) ? http_build_query($query) : $query;
|
||||
$this->query = empty($this->query) ? $query : $this->query . '&' . $query;
|
||||
@ -198,13 +190,13 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* 设置需要POST的数据
|
||||
*
|
||||
* @access public
|
||||
* @param array $data 需要POST的数据
|
||||
* @return Typecho_Http_Client_Adapter
|
||||
* @param array|string $data 需要POST的数据
|
||||
* @return $this
|
||||
*/
|
||||
public function setData($data)
|
||||
public function setData($data): Adapter
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->setMethod(Typecho_Http_Client::METHOD_POST);
|
||||
$this->setMethod(Client::METHOD_POST);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -213,9 +205,9 @@ abstract class Typecho_Http_Client_Adapter
|
||||
*
|
||||
* @access public
|
||||
* @param string $method
|
||||
* @return Typecho_Http_Client_Adapter
|
||||
* @return $this
|
||||
*/
|
||||
public function setMethod($method)
|
||||
public function setMethod(string $method): Adapter
|
||||
{
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
@ -226,12 +218,12 @@ abstract class Typecho_Http_Client_Adapter
|
||||
*
|
||||
* @access public
|
||||
* @param array $files 需要POST的文件
|
||||
* @return Typecho_Http_Client_Adapter
|
||||
* @return $this
|
||||
*/
|
||||
public function setFiles(array $files)
|
||||
public function setFiles(array $files): Adapter
|
||||
{
|
||||
$this->files = empty($this->files) ? $files : array_merge($this->files, $files);
|
||||
$this->setMethod(Typecho_Http_Client::METHOD_POST);
|
||||
$this->setMethod(Client::METHOD_POST);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -240,9 +232,9 @@ abstract class Typecho_Http_Client_Adapter
|
||||
*
|
||||
* @access public
|
||||
* @param integer $timeout 超时时间
|
||||
* @return Typecho_Http_Client_Adapter
|
||||
* @return $this
|
||||
*/
|
||||
public function setTimeout($timeout)
|
||||
public function setTimeout(int $timeout): Adapter
|
||||
{
|
||||
$this->timeout = $timeout;
|
||||
return $this;
|
||||
@ -253,9 +245,9 @@ abstract class Typecho_Http_Client_Adapter
|
||||
*
|
||||
* @access public
|
||||
* @param string $rfc http协议
|
||||
* @return Typecho_Http_Client_Adapter
|
||||
* @return $this
|
||||
*/
|
||||
public function setRfc($rfc)
|
||||
public function setRfc(string $rfc): Adapter
|
||||
{
|
||||
$this->rfc = $rfc;
|
||||
return $this;
|
||||
@ -266,9 +258,9 @@ abstract class Typecho_Http_Client_Adapter
|
||||
*
|
||||
* @access public
|
||||
* @param string $ip ip地址
|
||||
* @return Typecho_Http_Client_Adapter
|
||||
* @return $this
|
||||
*/
|
||||
public function setIp($ip)
|
||||
public function setIp(string $ip): Adapter
|
||||
{
|
||||
$this->ip = $ip;
|
||||
return $this;
|
||||
@ -279,21 +271,21 @@ abstract class Typecho_Http_Client_Adapter
|
||||
*
|
||||
* @access public
|
||||
* @param string $url 请求地址
|
||||
* @return string
|
||||
* @throws Typecho_Http_Client_Exception
|
||||
* @return string|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send($url)
|
||||
public function send(string $url): ?string
|
||||
{
|
||||
$params = parse_url($url);
|
||||
|
||||
if (!empty($params['host'])) {
|
||||
$this->host = $params['host'];
|
||||
} else {
|
||||
throw new Typecho_Http_Client_Exception('Unknown Host', 500);
|
||||
throw new Exception('Unknown Host', 500);
|
||||
}
|
||||
|
||||
if (!in_array($params['scheme'], ['http', 'https'])) {
|
||||
throw new Typecho_Http_Client_Exception('Unknown Scheme', 500);
|
||||
throw new Exception('Unknown Scheme', 500);
|
||||
}
|
||||
|
||||
if (!empty($params['path'])) {
|
||||
@ -313,7 +305,7 @@ abstract class Typecho_Http_Client_Adapter
|
||||
|
||||
$this->scheme = $params['scheme'];
|
||||
$this->port = ('https' == $params['scheme']) ? 443 : 80;
|
||||
$url = Typecho_Common::buildUrl($params);
|
||||
$url = Common::buildUrl($params);
|
||||
|
||||
if (!empty($params['port'])) {
|
||||
$this->port = $params['port'];
|
||||
@ -327,7 +319,7 @@ abstract class Typecho_Http_Client_Adapter
|
||||
$response = $this->httpSend($url);
|
||||
|
||||
if (!$response) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
str_replace("\r", '', $response);
|
||||
@ -374,9 +366,9 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* @access public
|
||||
* @param string $key 参数名称
|
||||
* @param string $value 参数值
|
||||
* @return Typecho_Http_Client_Adapter
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeader($key, $value)
|
||||
public function setHeader(string $key, string $value): Adapter
|
||||
{
|
||||
$key = str_replace(' ', '-', ucwords(str_replace('-', ' ', $key)));
|
||||
$this->headers[$key] = $value;
|
||||
@ -390,7 +382,7 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* @param string $url 请求地址
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function httpSend($url);
|
||||
abstract protected function httpSend(string $url): string;
|
||||
|
||||
/**
|
||||
* 获取回执的头部信息
|
||||
@ -399,7 +391,7 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* @param string $key 头信息名称
|
||||
* @return string
|
||||
*/
|
||||
public function getResponseHeader($key)
|
||||
public function getResponseHeader(string $key): ?string
|
||||
{
|
||||
$key = strtolower($key);
|
||||
return $this->responseHeader[$key] ?? null;
|
||||
@ -411,7 +403,7 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getResponseStatus()
|
||||
public function getResponseStatus(): int
|
||||
{
|
||||
return $this->responseStatus;
|
||||
}
|
||||
@ -422,7 +414,7 @@ abstract class Typecho_Http_Client_Adapter
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getResponseBody()
|
||||
public function getResponseBody(): string
|
||||
{
|
||||
return $this->responseBody;
|
||||
}
|
||||
|
@ -1,15 +1,13 @@
|
||||
<?php
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
/**
|
||||
* CURL适配器
|
||||
*
|
||||
* @author qining
|
||||
* @category typecho
|
||||
* @package Http
|
||||
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
|
||||
* @license GNU General Public License 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
namespace Typecho\Http\Client\Adapter;
|
||||
|
||||
use Typecho\Http\Client;
|
||||
use Typecho\Http\Client\Adapter;
|
||||
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* CURL适配器
|
||||
@ -18,7 +16,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
* @category typecho
|
||||
* @package Http
|
||||
*/
|
||||
class Typecho_Http_Client_Adapter_Curl extends Typecho_Http_Client_Adapter
|
||||
class Curl extends Adapter
|
||||
{
|
||||
/**
|
||||
* 判断适配器是否可用
|
||||
@ -26,7 +24,7 @@ class Typecho_Http_Client_Adapter_Curl extends Typecho_Http_Client_Adapter
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailable()
|
||||
public static function isAvailable(): bool
|
||||
{
|
||||
return function_exists('curl_version');
|
||||
}
|
||||
@ -37,8 +35,9 @@ class Typecho_Http_Client_Adapter_Curl extends Typecho_Http_Client_Adapter
|
||||
* @access public
|
||||
* @param string $url 请求地址
|
||||
* @return string
|
||||
* @throws Client\Exception
|
||||
*/
|
||||
protected function httpSend($url)
|
||||
protected function httpSend(string $url): string
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
||||
@ -93,17 +92,21 @@ class Typecho_Http_Client_Adapter_Curl extends Typecho_Http_Client_Adapter
|
||||
}
|
||||
|
||||
/** POST模式 */
|
||||
if (Typecho_Http_Client::METHOD_POST == $this->method) {
|
||||
if (Client::METHOD_POST == $this->method) {
|
||||
if (!isset($this->headers['content-type'])) {
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
}
|
||||
|
||||
if (!empty($this->data)) {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($this->data) ? http_build_query($this->data) : $this->data);
|
||||
curl_setopt(
|
||||
$ch,
|
||||
CURLOPT_POSTFIELDS,
|
||||
is_array($this->data) ? http_build_query($this->data) : $this->data
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($this->files)) {
|
||||
foreach ($this->files as $key => &$file) {
|
||||
foreach ($this->files as &$file) {
|
||||
$file = '@' . $file;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->files);
|
||||
@ -112,7 +115,7 @@ class Typecho_Http_Client_Adapter_Curl extends Typecho_Http_Client_Adapter
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if (false === $response) {
|
||||
throw new Typecho_Http_Client_Exception(curl_error($ch), 500);
|
||||
throw new Client\Exception(curl_error($ch), 500);
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user