Files
BESCMS/dayrui/Fcms/Model/Attachment.php
T

435 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php namespace Phpcmf\Model;
/**
* https://www.besyun.com
* BESCMS
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
**/
/**
* 附件模型
*/
class Attachment extends \Phpcmf\Model {
public function __construct() {
parent::__construct();
$this->siteid = SITE_ID;
}
// 验证用户权限
public function check($member, $siteid) {
if (IS_ADMIN) {
// 后台不验证
return dr_return_data(1);
}
$this->member = $member;
$this->siteid = $siteid;
$error = '';
if ($member['is_admin']) {
// 管理员不验证
} elseif (IS_USE_MEMBER && !\Phpcmf\Service::L('member_auth', 'member')->member_auth('uploadfile', $this->member)) {
$error = dr_lang('您的用户组不允许上传文件');
} elseif (!IS_USE_MEMBER && (!defined('SYS_ATTACHMENT_GUEST') || !SYS_ATTACHMENT_GUEST)) {
$error = dr_lang('游客不允许上传文件');
}
// 挂钩点 验证格式
$rt2 = \Phpcmf\Hooks::trigger_callback('check_upload_auth', $this->member, $error);
if ($rt2 && isset($rt2['code'])) {
$error = $rt2['code'] ? '' : $rt2['msg'];
}
if ($error) {
return dr_return_data(0, $error);
}
return dr_return_data(1);
}
// 附件归属
public function handle($uid, $related, $data) {
if (!SYS_ATTACHMENT_DB) {
return;
}
$uid = intval($uid);
$member = dr_member_info($uid);
// 删除文件
if ($data['del'] && $related && $related != 'rand') {
$delete = $this->table('attachment')->where_in('id', $data['del'])->getAll();
if ($delete) {
foreach ($delete as $row) {
if ($related == $row['related']) {
$this->file_delete($member, $row['id']);
}
}
}
}
// 新增归档
if ($data['add']) {
foreach ($data['add'] as $id) {
$id = is_numeric($id) ? intval($id) : 0;
if (!$id) {
continue;
}
$t = $this->table('attachment_unused')->get($id);
if ($t) {
// 更新主索引表
$this->table('attachment')->update($id, array(
'uid' => $t['uid'],
'author' => '',
'tableid' => 0,
'related' => $related
));
$this->table('attachment_data')->insert(array(
'id' => $t['id'],
'uid' => $t['uid'],
'remote' => $t['remote'],
'author' => '',
'related' => $related,
'fileext' => $t['fileext'],
'filesize' => $t['filesize'],
'filename' => $t['filename'],
'inputtime' => $t['inputtime'],
'attachment' => $t['attachment'],
'attachinfo' => $t['attachinfo'],
));
// 删除未使用附件
$this->table('attachment_unused')->delete($id);
} else {
// 已使用的附件库
$t = $this->table('attachment_data')->get($id);
if ($t) {
if (strpos($t['related'], 'ueditor') !== false) {
// 编辑器字段归属
$this->table('attachment')->update($id, array(
'related' => $related
));
$this->table('attachment_data')->update($id, array(
'related' => $related
));
} elseif ($t['related'] != $related) {
// 表示多表复用
$this->table('attachment')->update($id, array(
'related' => 'rand'
));
$this->table('attachment_data')->update($id, array(
'related' => 'rand'
));
} else {
// 表示多表复用
$this->table('attachment')->update($id, array(
'related' => $related.'-rand'
));
$this->table('attachment_data')->update($id, array(
'related' => $related.'-rand'
));
}
}
}
}
}
}
// 删除内容关联的文件
public function cid_delete($member, $cid, $related) {
if (!$cid) {
return;
} elseif (!IS_ADMIN && !$member) {
return;
}
$indexs = $this->table('attachment')->where('related', $related.'-'.$cid)->getAll();
if ($indexs) {
foreach ($indexs as $i) {
$this->file_delete($member, intval($i['id']));
}
}
}
// 删除用户的全部关联的文件
public function uid_delete($uid) {
if (!$uid ) {
return;
}
$indexs = $this->table('attachment')->where('uid', $uid)->getAll();
if ($indexs) {
foreach ($indexs as $i) {
$this->file_delete($uid, intval($i['id']));
}
}
}
// 删除内容关联的文件
public function id_delete($member, $ids, $related) {
if (!$member || !$ids) {
return;
}
foreach ($ids as $id) {
$indexs = $this->table('attachment')->where('related', $related.'-'.$id)->getAll();
if ($indexs) {
foreach ($indexs as $i) {
$this->file_delete($member, intval($i['id']));
}
}
}
}
// related删除
public function related_delete($related, $id = 0) {
if ($id) {
$indexs = $this->table('attachment')->where('related', $related.'-'.$id)->getAll();
} else {
$indexs = $this->table('attachment')->where('related LIKE "'.$related.'-%"')->getAll();
}
if ($indexs) {
foreach ($indexs as $index) {
$this->_delete_file($index);
}
}
}
// 删除文件判断
public function file_delete($member, $id) {
if (!$member) {
return dr_return_data(0, dr_lang('必须登录之后才能删除文件'));
} elseif (!$id) {
return dr_return_data(0, dr_lang('文件id不存在'));
} elseif (!isset($member['id'])) {
return dr_return_data(0, dr_lang('必须登录之后才能删除文件'));
}
if (is_numeric($member)) {
$member = $this->table('member')->get($member);
if (!$member) {
return dr_return_data(0, dr_lang('必须登录之后才能删除文件'));
}
}
$index = $this->table('attachment')->get($id);
if (!$index) {
return dr_return_data(0, dr_lang('文件记录不存在'));
}
if (IS_ADMIN) {
// 后台删除
if (!\Phpcmf\Service::M('auth')->_is_admin_auth('attachments/del')) {
return dr_return_data(0, dr_lang('无权限操作'));
}
} else {
// 前端删除自己的
if ($member['id'] != $index['uid']) {
return dr_return_data(0, dr_lang('不能删除他人的文件'));
}
}
return $this->_delete_file($index);
}
// 开始删除文件
public function _delete_file($index) {
$table = $index['related'] ? 'attachment_data' : 'attachment_unused';
// 获取文件信息
$info = $this->table($table)->get($index['id']);
if (!$info) {
$this->table('attachment')->delete($index['id']);
return dr_return_data(0, dr_lang('文件数据不存在'));
}
$rt = $this->table('attachment')->delete($index['id']);
if (!$rt['code']) {
return dr_return_data(0, $rt['msg']);
}
// 删除记录
$this->table($table)->delete($index['id']);
// 开始删除文件
$storage = new \Phpcmf\Library\Storage(\Phpcmf\Service::C());
$storage->delete($this->get_attach_info($info['remote']), $info['attachment']);
// 删除缓存
$this->clear_data($index);
// 删除附件进行记录
\Phpcmf\Service::L('input')->system_log('删除附件(#'.$index['id'].'-'.dr_now_url().''.var_export($info, true));
if (CI_DEBUG) {
log_message('debug', '删除附件(#'.$index['id'].''.dr_get_file_url($info));
}
return dr_return_data(1, dr_lang('删除成功'));
}
// 删除附件缓存
public function clear_data($index) {
\Phpcmf\Service::L('cache')->del_file('attach-info-'.$index['id'], 'attach');
// 删除缩略图的缓存
if (in_array($index['fileext'], ['png', 'jpeg', 'jpg', 'gif'])) {
list($cache_path, $a, $b, $path) = dr_thumb_path($index['id']);
dr_dir_delete($cache_path.'/'.$path.'/', true);
}
}
// 附件归档存储
// $handle是否强制随机储存已使用
public function save_data($data, $related = '', $handle = 0) {
if (!$this->member) {
$this->member = [
'id'=> 0,
'username' => 'guest',
];
}
// 按uid散列分表
$tid = (int)substr((string)$this->member['id'], -1, 1);
$related = $related ? $related : (SYS_ATTACHMENT_DB ? '' : 'rand');
$data['name'] = dr_safe_replace($data['name'], ["/", '\\', '..']);
// 入库索引表
$rt = $this->table('attachment')->replace([
'uid' => (int)$this->member['id'],
'author' => '',
'siteid' => $this->siteid,
'related' => $related,
'tableid' => $tid,
'download' => 0,
'filesize' => (int)$data['size'],
'fileext' => $data['ext'],
'filemd5' => $data['md5'] ? $data['md5'] : 0,
]);
if (!$rt['code']) {
// 入库失败
unlink($data['path']);
return $rt;
}
$id = $rt['code'];
if ($handle == 0 && (strpos($related, 'ueditor') === 0 ? 0 : SYS_ATTACHMENT_DB)) {
// 归档存储
$rt = $this->table('attachment_unused')->replace([
'id' => $id,
'uid' => (int)$this->member['id'],
'author' => '',
'siteid' => $this->siteid,
'remote' => $data['remote'],
'fileext' => $data['ext'],
'filename' => $data['name'],
'filesize' => (int)$data['size'],
'inputtime' => SYS_TIME,
'attachment' => $data['file'],
'attachinfo' => dr_safe_url($_SERVER['HTTP_REFERER']),
]);
} else {
// 随机存储
$rt = $this->table('attachment_data')->replace([
'id' => $id,
'uid' => (int)$this->member['id'],
'author' => '',
'related' => $related,
'filename' => $data['name'],
'fileext' => $data['ext'],
'filesize' => $data['size'],
'remote' => $data['remote'],
'attachinfo' => dr_array2string($data['info']),
'attachment' => $data['file'],
'inputtime' => SYS_TIME,
]);
}
// 入库失败 无主键id 返回msg为准
if ($rt['msg']) {
// 删除附件索引
unlink($data['path']);
$this->table('attachment')->delete($id);
return dr_return_data(0, $rt['msg']);
}
// 统计附件插件
if (dr_is_app('mfile')) {
\Phpcmf\Service::M('mfile', 'mfile')->update_member($this->member, $data['size']);
}
return dr_return_data($id, 'ok');
}
// 附件存储信息
public function get_attach_info($id = 0, $image_reduce = 0) {
// 全局存储
if ((!$id || $id == 'null') && SYS_ATTACHMENT_SAVE_ID) {
$id = SYS_ATTACHMENT_SAVE_ID;
}
$remote = \Phpcmf\Service::C()->get_cache('attachment');
if (isset($remote[$id]) && $remote[$id]) {
$rt = $remote[$id];
$rt['image_reduce'] = $image_reduce;
return $rt;
}
return [
'id' => 0,
'url' => SYS_UPLOAD_URL,
'type' => 0,
'image_reduce' => $image_reduce,
'value' => [
'path' => SYS_UPLOAD_PATH
]
];
}
// 存储aid到内存中
public function save_ueditor_aid($rid, $aid) {
$name = 'ueditor_aid_'.$rid;
$data = dr_string2array(\Phpcmf\Service::L('cache')->get_auth_data($name));
if (!$data || !is_array($data)) {
$data = [$aid];
} else {
$data[] = $aid;
}
\Phpcmf\Service::L('cache')->set_auth_data($name, $data);
}
// 读取aid
public function get_ueditor_aid($rid, $is_del = false) {
$name = 'ueditor_aid_'.$rid;
$data = \Phpcmf\Service::L('cache')->get_auth_data($name);
$is_del && \Phpcmf\Service::L('cache')->del_auth_data($name);
return $data;
}
// 远程附件缓存
public function cache($site = SITE_ID) {
$data = $this->table('attachment_remote')->getAll();
$cache = [];
if ($data) {
foreach ($data as $t) {
$t['url'] = trim($t['url'], '/').'/';
$t['value'] = dr_string2array($t['value']);
$t['value'] = $t['value'][intval($t['type'])];
$cache[$t['id']] = $t;
}
}
\Phpcmf\Service::L('cache')->set_file('attachment', $cache);
}
}