Skip to content
Permalink
Browse files

文章图片/附件管理

  • Loading branch information...
movsb committed May 23, 2017
1 parent cdc52f6 commit c5505ed2df0aa2b6d6ee4b9894f7891bb0b42f35
Showing with 290 additions and 1 deletion.
  1. +1 −0 .gitignore
  2. +113 −0 admin/file-upload.php
  3. +158 −1 admin/post.php
  4. +16 −0 admin/query.php
  5. +2 −0 setup/config.sample.php
@@ -1,4 +1,5 @@
*~
*.swp
/contents/
/files/

@@ -0,0 +1,113 @@
<?php
if($_SERVER['REQUEST_METHOD'] == 'GET') :
else :
function fm_die_json($arg) {
header('HTTP/1.1 200 OK');
header('Content-Type: application/json');
echo json_encode($arg);
die(0);
}
function fm_error($msg) {
fm_die_json([
'errno' => 'error',
'error' => $msg,
]);
}
require_once('login-auth.php');
if(!login_auth()) {
fm_error('需要登录后才能进行该操作!');
}
require_once('load.php');
function fm_upload() {
$pid = (int)($_POST['pid'] ?? 0);
if($pid <= 0) {
fm_error('无效文章编号。');
}
$root = TBPATH.'/'.FILE_DIR.'/'.$pid;
if(!is_dir($root)) {
if(!@mkdir($root, 0777, true)) {
fm_error('无法创建上传文件保存目录。');
}
}
$count = 0;
foreach($_FILES['files']['error'] as $index => $error) {
$count++;
if($error === 0) {
$tmp_name = $_FILES['files']['tmp_name'][$index];
$name = basename($_FILES['files']['name'][$index]);
$path = "$root/$name";
if(@move_uploaded_file($tmp_name, $path)) {
$count--;
}
}
}
if($count != 0) {
}
fm_die_json([
'errno' => 'ok',
]);
}
function fm_list() {
$pid = (int)($_POST['pid'] ?? 0);
$root = TBPATH.'/'.FILE_DIR.'/'.$pid;
$files = [];
if($handle = opendir($root)) {
while(($file = readdir($handle)) !== false) {
if($file[0] != '.') {
$files[] = $file;
}
}
}
fm_die_json([
'errno' => 'ok',
'files' => $files,
]);
}
function fm_delete() {
$pid = (int)($_POST['pid'] ?? 0);
$root = TBPATH.'/'.FILE_DIR.'/'.$pid;
$name = basename($_POST['name'] ?? '');
$path = "$root/$name";
$R = @unlink($path);
fm_die_json([
'errno' => $R ? 'ok' : 'error',
]);
}
$do = $_POST['do'] ?? '';
if($do === 'upload') fm_upload();
else if($do === 'list') fm_list();
else if($do === 'delete') fm_delete();
else error('error');
endif;
@@ -19,6 +19,163 @@ function post_widget_tag($p=null) {
add_hook('post_widget', 'post_widget_tag');
function post_widget_files($p=null) {
$title = '文件';
$classname = 'files';
$types = 'page,post';
$content = <<<EOD
<label>文件列表:</label>
<ul class="list">
</ul>
<label>文件上传:</label>
<div>
<input type="file" multiple class="files"/>
<button class="submit">上传</button>
<button class="refresh">刷新</button>
<progress class="progress"></progress>
</div>
<script>
function refresh_files() {
var pid = $('#form-post input[name="id"]').val();
$.post('file-upload.php',
{
pid: pid,
do: 'list',
},
function(data) {
if(data.errno == 'ok') {
var files = $('.widget-files .list');
files.empty();
data.files.forEach(function(file) {
files.append(
$('<li/>')
.append($('<span/>').text(file))
.append('<button class="delete">删除</button>')
);
});
bind_delete();
}
}
);
}
$('.widget-files .refresh').click(function(){
refresh_files();
return false;
});
function bind_delete() {
$('.widget-files .list .delete').click(function(){
var li = $(this).parent();
var name = $(this).prev().text();
var pid = $('#form-post input[name="id"]').val();
$.post('file-upload.php',
{
pid: pid,
do: 'delete',
name: name,
},
function(data) {
if(data.errno == 'ok') {
li.remove();
}
else {
alert('删除失败。');
}
}
);
return false;
});
}
$('.widget-files .submit').click(function(){
var files = $('.widget-files .files')[0].files;
if(files.length <= 0) {
alert('请先选择文件再上传。');
return false;
}
var data = new FormData();
// 当前文章ID(新文章并没有ID,这里先临时使用下一篇文章ID)
// 所以,不能同时编辑并发表新文章
var pid = $('#form-post input[name="id"]').val();
data.append('pid', pid);
data.append('do', 'upload');
// 待上传的文件列表
for(var i = 0, n = files.length; i < n; i++) {
var file = files[i];
data.append('files[]', file);
}
// 进度条
var progress = $('.widget-files .progress');
progress.attr('value', 0);
// https://stackoverflow.com/a/8758614/3628322
$.ajax({
// Your server script to process the upload
url: 'file-upload.php',
type: 'POST',
// Form data
data: data,
// Tell jQuery not to process data or worry about content-type
// You *must* include these options!
cache: false,
contentType: false,
processData: false,
// Custom XMLHttpRequest
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
// For handling the progress of the upload
myXhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
progress.attr({
value: e.loaded,
max: e.total,
});
}
} , false);
}
return myXhr;
},
error: function(xhr, except) {
console.warn(xhr,except);
alert('ajax error:'+xhr.statusText);
},
success: function(response) {
console.log('data:',response);
if(response.errno === 'ok') {
refresh_files();
}
else {
alert(response.error);
}
},
});
return false;
});
</script>
EOD;
return compact('title', 'classname', 'types', 'content');
}
add_hook('post_widget', 'post_widget_files');
function post_widget_metas($p=null) {
$metas = str_replace(['\\','\''], ['\\\\','\\\''], $p ? $p->metas_raw : '{}');
$title = '自定义';
@@ -386,7 +543,7 @@ function new_post_html($p=null){
<div>
<input type="hidden" name="do" value="<?php echo $p ? 'update' : 'new'; ?>" />
<input type="hidden" name="type" value="<?php echo $p ? $p->type : $type; ?>" />
<?php if($p) { ?><input type="hidden" name="id" value="<?php echo $p->id; ?>" /><?php } ?>
<input type="hidden" name="id" value="<?php echo $p ? $p->id : $next_id; ?>" />
</div>
</div><!-- post-area -->
<div class="sidebar sidebar-left">
@@ -75,6 +75,7 @@ public function query() {
$rules = [
'^/(\d+)(/)?$' => 'short=1&id=$1&slash=$2',
'^(/\d+/[^/]+)$' => 'file=$1',
'^/archives/(\d+)\.html$' => 'id=$1',
'^/date/((\d{4})/((\d{2})/)?)$' => 'yy=$2&mm=$4',
'^/(.+)/([^/]+)\.html$' => 'long=1&tax=$1&slug=$2',
@@ -139,6 +140,21 @@ public function query() {
die(0);
}
// 处理文件
if(isset($this->internal_query['file'])) {
$relative = '/'.FILE_DIR.$this->internal_query['file'];
$absolute = TBPATH.$relative;
if($logged_in && file_exists($absolute)) {
header('HTTP/1.1 302 Use local file');
header('Location: '.$relative);
}
else {
header('HTTP/1.1 302 Use backup file');
header('Location: '.FILE_HOST.$relative);
}
die(0);
}
// 处理RSS
if($this->is_query_modification && isset($this->internal_query['feed'])) {
if($tbdate->mysql_local_to_http_gmt($tbopt->get('last_post_time')) === $_SERVER['HTTP_IF_MODIFIED_SINCE']) {
@@ -1,6 +1,8 @@
<?php
define('TBPATH', dirname(__FILE__).'/../');
define('FILE_HOST', 'http://localhost');
define('FILE_DIR', 'files');
define('TB_PRIVATE', FALSE); /* 是否对外开放 */
define('TB_THEME', 'blog'); /* 主题 */

0 comments on commit c5505ed

Please sign in to comment.
You can’t perform that action at this time.