EasyImages2.0/admin/filer.php

1124 lines
38 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
/**
* Powered by https://github.com/rehiy/web-indexr
*/
/**开始 - 自定义修改 */
require_once __DIR__ . '/../app/function.php';
require_once __DIR__ . '/../config/config.php';
// 开启tinyfilemanager文件管理
if (!$config['file_manage']) {
require_once APP_ROOT . '/app/header.php';
echo '<h4 class="alert alert-danger">文件管理已关闭~~</h4>';
header("refresh:3;url=" . $config['domain'] . '?manag-closed');
exit(require_once APP_ROOT . '/app/footer.php');
}
/**结束 - 自定义修改 */
// 目录绝对路径,结尾不加 `/`
// RexHelper::$root = $_SERVER['DOCUMENT_ROOT'];
RexHelper::$root = $_SERVER['DOCUMENT_ROOT'];
// 系统用户列表,密码类型 MD5
RexHelper::$users[$config['user']] = array(
'password' => $config['password']
);
// 可编辑文件后缀,开头不加 `.`
// RexHelper::$text_suff[] = "jsx";
// RexHelper::$text_suff[] = "php5";
// 文件排除规则,仅正则表达式
RexHelper::$ignore_list = array(
'/^\.git|.php|.htaccess|robots.txt|favicon.ico|README.md/', '/^admin|api|app|config|docs|install|public/'
);
session_start();
?>
<!DOCTYPE html>
<html lang="zh-Hans-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit" />
<meta name="force-rendering" content="webkit" />
<meta name="author" content="Icret EasyImage2.0">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>文件管理 - <?php echo $config['title']; ?></title>
<meta name="keywords" content="<?php echo $config['keywords']; ?>" />
<meta name="description" content="<?php echo $config['description']; ?>" />
<link rel="shortcut icon" href="<?php static_cdn(); ?>/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="<?php static_cdn(); ?>/public/static/zui/css/zui.min.css">
<script type="application/javascript" src="<?php static_cdn(); ?>/public/static/zui/lib/jquery/jquery-3.6.0.min.js"></script>
<script type="application/javascript" src="<?php static_cdn(); ?>/public/static/zui/js/zui.min.js"></script>
<style type="text/css">
body {
font-size: 14px;
}
a {
text-decoration: none;
}
.login {
margin: 100px auto;
max-width: 95%;
width: 320px;
}
.view-image {
max-width: 95%;
width: 320px;
}
</style>
</head>
<body>
<?php
// 模块参数
$view = G('view');
$action = G('action');
$path = G('path', '/');
// 已登陆
if (RexAction::user_info()) {
if ($action) {
RexAction::action($path, $action);
} else {
RExplorer::body_navbar($path, $view);
echo '<div class="container">';
RExplorer::body_breadcrumb($path);
RExplorer::index($path, $view);
echo '</div>';
}
}
// 未登录
else {
if ($action == 'login') {
RexAction::action($path, $action);
} else {
RExplorer::view_login($path);
}
}
?>
<script type="text/javascript">
function do_cofirm(url, act) {
var i = 0;
while (i++ < 3) {
if (!confirm(i + '.重要的操作要重复问三遍,您确定要' + act + '吗?')) {
return false;
}
}
location.href = url;
}
</script>
</body>
</html>
<?php
/**
* 获取参数
* @param string $name
* @param mixed $defv
* @return mixed
*/
function G($name, $defv = '')
{
if (isset($_REQUEST[$name])) {
return $_REQUEST[$name];
}
return $defv;
}
/**
* 页面主类
*/
class RExplorer
{
/**
* 显示网站目录的项目内容
*/
static function index($path, $view)
{
$method = 'view_' . $view;
if (method_exists('RExplorer', $method)) {
return self::$method($path);
}
// 查看路径
$sapath = RexHelper::path_rtoa($path);
if (is_dir($sapath)) {
return self::view_list($path);
}
if (is_file($sapath)) {
return self::view_edit($path);
}
echo '<strong class="red">路径不存在或无权限访问!</strong>';
}
/**
* 用户登录视图
* @param string $path 路径
*/
static function view_login($path)
{
echo '
<div class="login"">
<form class="form-horizontal" method="post" action="?action=login">
<h5 class="card-title text-center mb-5">文件管理 <small>v' . RexHelper::$version . '</small></h5>
<div class="form-group">
<label for="exampleInputEmail3">账号</label>
<input type="text" class="form-control" name="username" id="exampleInputEmail3" placeholder="登录账号">
</div>
<div class="form-group">
<label for="exampleInputInviteCode3">密码</label>
<input type="password" class="form-control" name="password" id="exampleInputInviteCode3" placeholder="登录密码">
</div>
<button type="submit" class="btn btn-primary">登录</button>
</form>
</div>';
}
/**
* 目录内容视图
* @param string $path 路径
*/
static function view_list($path)
{
$sapath = RexHelper::path_rtoa($path);
$fslist = iterator_to_array(new FilesystemIterator($sapath, 256));
ksort($fslist, SORT_NATURAL);
usort($fslist, function ($a, $b) {
if ($a->isDir() && !$b->isDir()) {
return -1;
}
if (!$a->isDir() && $b->isDir()) {
return 1;
}
return 0;
});
echo '
<div class="table-responsive table-condensed">
<table class="table table-hover table-striped table-bordered text-nowrap">
<thead>
<tr>
<th scope="col">名称</th>
<th scope="col">大小</th>
<th scope="col" class="d-none d-sm-table-cell">权限</th>
<th scope="col" class="d-none d-md-table-cell">所有者</th>
<th scope="col">创建时间</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
';
foreach ($fslist as $item) {
$suffix = $item->isDir() ? '/' : '';
$srpath = RexHelper::path_ator($item->getRealPath());
if (RexHelper::is_ignore($item->getFileName())) {
continue;
}
echo '<tr>';
if (RexHelper::file_catetory($srpath) == 'image') {
echo '
<td>
<img data-toggle="lightbox" src="../app/thumb.php?img=', $srpath, '" data-image="' . $srpath . '" data-caption="查看原图" class="img-thumbnail" alt="查看原图" width="80">
</td>';
} else {
echo '
<td>
<a href="?path=' . $srpath . '">' . $item->getFileName() . $suffix . '</a>
</td>';
}
echo '
<td>' . ($item->isFile() ? RexHelper::format_bytes($item->getSize()) : '-') . '</td>
<td class="d-none d-sm-table-cell">' . substr(sprintf('%o', $item->getPerms()), -4) . '</td>
<td class="d-none d-md-table-cell">' . $item->getOwner() . ':' . $item->getGroup() . '<td>' . date('Y-m-d H:i', $item->getCTime()) . '</td>
<td><a href="?path=' . $srpath . '">查看</a>|<a href="?view=rename&path=' . $srpath . '">改名</a>|<a href="?view=chmod&path=' . $srpath . '">权限</a>|<a href="javascript:;" onclick="do_cofirm(\'?action=delete&path=' . $srpath . '\', \'删除\')">删除</a></td>
</tr>
';
}
echo '
</tbody>
</table>
';
}
/**
* 新增目录视图
* @param string $path 路径
*/
static function view_newdir($path)
{
echo '
<div class="newdir">
<form method="post" action="?action=newdir&path=' . $path . '">
<div class="row mb-3">
<label class="col-sm-2 col-form-label">目录名</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="filename">
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-form-label">权限模式</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="mode" value="0777">
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark">创建目录</button>
</div>
</form>
</div>
';
}
/**
* 新增文件视图
* @param string $path 路径
*/
static function view_newfile($path)
{
echo '
<div class="newfile">
<form method="post" action="?action=newfile&path=' . $path . '">
<div class="row mb-3">
<label class="col-sm-2 col-form-label">文件名</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="filename" placeholder="如newfile.txt">
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-form-label">内容</label>
<div class="col-sm-10">
<textarea class="form-control" name="content" rows="10"></textarea>
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark">创建文件</button>
</div>
</form>
</div>
';
}
/**
* 编辑文件内容视图
* @param string $path 路径
*/
static function view_edit($path)
{
$sapath = RexHelper::path_rtoa($path);
$category = RexHelper::file_catetory($sapath);
switch ($category) {
case 'text':
$c = htmlspecialchars(file_get_contents($sapath));
echo '
<div class="edit">
<form method="post" action="?action=edit&path=' . $path . '">
<div class="mb-4">
<textarea class="form-control" name="content" rows="30">' . $c . '</textarea>
</div>
<div class="d-grid">
';
if (is_writable($sapath)) {
echo '<button type="submit" class="btn btn-dark">保存文件</button>';
} else {
echo '<button class="btn btn-dark" disabled>文件不可写</button>';
}
echo '
</div>
</form>
</div>
';
return;
case 'image':
echo '
<div class="card view-image">
<img src="', $path, '" class="card-img-top">
<div class="card-body">
<a href="', $path, '" class="card-link">查看原图</a>
</div>
</div>
';
return;
default:
echo '
<div class="card">
<div class="card-body">
<a href="', $path, '" class="card-link">下载文件</a>
</div>
</div>
';
return;
}
}
/**
* 上传文件视图
* @param string $path 路径
*/
static function view_upload($path)
{
echo '
<div class="upload">
<form method="post" enctype="multipart/form-data" action="?action=upload&path=' . $path . '">
<div class="row mb-4">
<label class="col-sm-2 col-form-label">远程 URL</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="url">
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-form-label">本地文件</label>
<div class="col-sm-10">
<input type="file" class="form-control" name="file">
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark">立即上传</button>
</div>
</form>
</div>
';
}
/**
* 重命名文件视图
* @param string $path 路径
*/
static function view_rename($path)
{
echo '
<div class="rename">
<form method="post" action="?action=rename&path=' . $path . '">
<div class="row mb-3">
<label class="col-sm-2 col-form-label">原名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" value="' . basename($path) . '" readonly>
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-form-label">新名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="filename">
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark">重命名</button>
</div>
</form>
</div>
';
}
/**
* 编辑权限视图
* @param string $path 路径
*/
static function view_chmod($path)
{
$sapath = RexHelper::path_rtoa($path);
$perms = substr(sprintf("%o", fileperms($sapath)), -4);
echo '
<div class="chmod">
<form method="post" action="?action=chmod&path=' . $path . '">
<div class="row mb-3">
<label class="col-sm-2 col-form-label">名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" value="' . basename($path) . '" disabled>
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-form-label">权限模式</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="mode" value="' . $perms . '">
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark">设置</button>
</div>
</form>
</div>
';
}
/**
* 压缩文件视图
* @param string $path 路径
*/
static function view_zip($path)
{
echo '
<div class="zip">
<form method="post" action="?action=zip&path=' . $path . '">
<div class="row mb-3">
<label class="col-sm-2 col-form-label">压缩文件名</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="filename" value="/test.zip">
</div>
</div>
<div class="row mb-4">
<label class="col-sm-2 col-form-label">文件列表</label>
<div class="col-sm-10">
<textarea class="form-control" name="content" rows="10">' . $path . '</textarea>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-2 col-form-label">去除根路径</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="trimpath" placeholder="/www">
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark">压缩</button>
</div>
</form>
<div class="alert alert-secondary mt-2" role="alert">
注意,所有路径都相对于目录 ' . RexHelper::$root . '<br />
文件列表:每个路径一行,支持排除路径<br />
包含路径示例:/www/app<br />
排除路径示例exclude /www/app/log<br />
</div>
</div>
';
}
/**
* 解压缩文件视图
* @param string $path 路径
*/
static function view_unzip($path)
{
echo '
<div class="unzip">
<form method="post" action="?action=unzip&path=' . $path . '">
<div class="row mb-3">
<label class="col-sm-2 col-form-label">压缩包路径</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="filename" value="/test.zip">
</div>
</div>
<div class="row mb-3">
<label class="col-sm-2 col-form-label">解压缩路径</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="root" value="' . $path . '">
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark">解压</button>
</div>
<div class="alert alert-secondary mt-2" role="alert">
注意,所有路径都相对于' . RexHelper::$root . '
</div>
</form>
</div>
';
}
/**
* 全局操作菜单
* @param string $path 路径
* @param string $view 视图
*/
static function body_navbar($path, $view)
{
$pdir = $path;
if (!is_dir(RexHelper::path_rtoa($path))) {
$pdir = dirname($path);
}
$member = RexAction::user_info();
echo '
<nav class="navbar navbar-inverse" role="navigation">
<div class="container-fluid">
<!-- 导航头部 -->
<div class="navbar-header">
<!-- 移动设备上的导航切换按钮 -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse-example">
<span class="sr-only">切换导航</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- 品牌名称或logo -->
<a class="navbar-brand" href="?">文件管理</a>
</div>
<!-- 导航项目 -->
<div class="collapse navbar-collapse navbar-collapse-example">
<!-- 一般导航项目 -->
<ul class="nav navbar-nav">
<li class="' . ($view == 'newdir' ? 'active' : '') . '"><a href="?view=newdir&path=' . $pdir . '">新建目录</a></li>
<li class="' . ($view == 'newfile' ? 'active' : '') . '"><a href="?view=newfile&path=' . $pdir . '">新建文件</a></li>
<li class="' . ($view == 'upload' ? 'active' : '') . '"><a href="?view=upload&path=' . $pdir . '">上传文件</a></li>
<li class="' . ($view == 'zip' ? 'active' : '') . '"><a href="?view=zip&path=' . $pdir . '">打包目录</a></li>
<li class="' . ($view == 'unzip' ? 'active' : '') . '"><a href="?view=unzip&path=' . $pdir . '">解压文件</a></li>
<li class="' . ($view == 'opreset' ? 'active' : '') . '"><a href="?action=opreset&path=' . $path . '">清空OPCache</a></li>
</ul>
<!-- 右侧的导航项目 -->
<ul class="nav navbar-nav navbar-right">
<li><a href="your/nice/url">欢迎您, ' . $member['username'] . '</a></li>
<li><a href="?action=logout">注销</a></li>
</ul>
</div>
</div>
</nav>';
}
/**
* 路径转为导航
* @param string $path 路径
*/
static function body_breadcrumb($path)
{
echo '
<nav class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="?path=/">HOME</a></li>
';
$full = '';
$items = explode('/', trim($path, '/'));
foreach ($items as $item) {
$full .= '/' . $item;
echo '<li class="breadcrumb-item"><a href="?path=', $full, '">', $item, '</a></li>';
}
echo '
</ol>
</nav>
';
}
/**
* URL重定向
* @param string $url 重定向的URL地址
* @param integer $sec 重定向的等待时间(秒)
* @param string $msg 重定向前的提示信息
* @return void
*/
static function url_redirect($url, $sec, $msg = '')
{
$url = str_replace(array("\n", "\r"), '', $url);
$msg = $sec == 1 ? '操作成功!' : '操作失败!';
$cat = $sec == 1 ? 'success' : 'danger';
echo '
<div class="container pt-3">
<div class="alert alert-' . $cat . '" role="alert">
' . $msg . $sec . '秒后重定向到 ' . $url . '
</div>
</div>
<script type="text/javascript">
setTimeout(function() {
location.href = "' . $url . '";
}, ' . $sec * 1000 . ');
</script>
';
exit('</body></html>');
}
}
/**
* 回调方法类
*/
class RexAction
{
static function action($path, $action)
{
$method = 'act_' . $action;
if (!method_exists('RexAction', $method)) {
RExplorer::url_redirect('?r=fail', 2, '接口不存在!');
}
self::$method($path);
}
/**
* 用户信息
* @return array | null
*/
static function user_info()
{
if (isset($_SESSION[RexHelper::$ssid])) {
return $_SESSION[RexHelper::$ssid];
}
}
/**
* 用户登录操作
*/
static function act_login()
{
$uname = G('username');
if (empty(RexHelper::$users[$uname])) {
RExplorer::url_redirect('?r=fail', 2, '用户不存在!');
}
if (RexHelper::$users[$uname]['password'] != hash('sha256', (G('password')))) {
RExplorer::url_redirect('?r=fail', 2, '密码错误!');
}
$_SESSION[RexHelper::$ssid] = array(
'username' => $uname,
);
RExplorer::url_redirect('?r=ok', 1);
}
/**
* 用户登出操作
*/
static function act_logout()
{
unset($_SESSION[RexHelper::$ssid]);
RExplorer::url_redirect('?r=ok', 1);
}
/**
* 保存新目录
* @param string $path 路径
*/
static function act_newdir($path)
{
$filename = G('filename');
if (!$filename) {
RExplorer::url_redirect('?path=' . $path, 2, '目录名称无效!');
}
$mode = intval(G('mode'), 8);
$sapath = RexHelper::path_rtoa($path);
$target = $sapath . DIRECTORY_SEPARATOR . $filename;
if (file_exists($target)) {
RExplorer::url_redirect('?path=' . $path, 2, ' 目标已存在!');
}
if (@mkdir($target, $mode)) {
RExplorer::url_redirect('?path=' . $path, 1);
}
RExplorer::url_redirect('?path=' . $path, 2);
}
/**
* 新建文件
* @param string $path 路径
*/
static function act_newfile($path)
{
$filename = G('filename');
if (!$filename || strpos($filename, '.') === false) {
RExplorer::url_redirect('?path=' . $path, 2, '文件名或扩展名无效!');
}
$content = G('content');
$sapath = RexHelper::path_rtoa($path);
is_dir($sapath) || $sapath = dirname($sapath); // 降级
$target = $sapath . DIRECTORY_SEPARATOR . $filename;
if (file_put_contents($target, $content) !== false) {
RExplorer::url_redirect('?path=' . $path, 1);
}
RExplorer::url_redirect('?path=' . $path, 2);
}
/**
* 修改文件
* @param string $path 路径
*/
static function act_edit($path)
{
$content = G('content');
$sapath = RexHelper::path_rtoa($path);
if (file_put_contents($sapath, $content) !== false) {
RExplorer::url_redirect('?path=' . $path, 1);
}
RExplorer::url_redirect('?path=' . $path, 2);
}
/**
* 删除路径(文件或目录)
* @param string $path 路径
*/
static function act_delete($path)
{
$sapath = RexHelper::path_rtoa($path);
if (is_file($sapath)) {
if (@unlink($sapath)) {
RExplorer::url_redirect('?path=' . dirname($path), 1);
}
RExplorer::url_redirect('?path=' . dirname($path), 2);
}
if (is_dir($sapath)) {
if (@rmdir($sapath)) {
RExplorer::url_redirect('?path=' . dirname($path), 1);
}
RExplorer::url_redirect('?path=' . $path, 2, '非空或权限不足!');
}
RExplorer::url_redirect('?path=' . $path, 2, '不是有效文件或目录!');
}
/**
* 上传文件
* @param string $path 路径
*/
static function act_upload($path)
{
$sapath = RexHelper::path_rtoa($path);
// 从远程获取
if ($fileurl = G('url')) {
if ($data = file_get_contents($fileurl)) {
$target = $sapath . DIRECTORY_SEPARATOR . basename($fileurl);
if (file_put_contents($target, $data)) {
RExplorer::url_redirect('?path=' . $path, 1);
}
RExplorer::url_redirect('?path=' . $path, 2, '保存文件失败');
}
RExplorer::url_redirect('?path=' . $path, 2, '获取源文件失败');
}
// 从本地上传
if (!empty($_FILES['file'])) {
if ($_FILES['file']['error']) {
$msg = '错误代码 ' . $_FILES['file']['error'];
RExplorer::url_redirect('?path=' . $path, 2, $msg);
}
$target = $sapath . DIRECTORY_SEPARATOR . $_FILES['file']['name'];
if (file_exists($target)) {
$msg = $_FILES['file']['name'] . ' 文件已存在!';
RExplorer::url_redirect('?path=' . $path, 2, $msg);
}
if (@move_uploaded_file($_FILES['file']['tmp_name'], $target)) {
RExplorer::url_redirect('?path=' . $path, 1);
}
RExplorer::url_redirect('?path=' . $path, 2);
}
// 参数错误
RExplorer::url_redirect('?path=' . $path, 2, '参数错误');
}
/**
* 重命名路径
* @param string $path 路径
*/
static function act_rename($path)
{
$filename = G('filename');
if (!$filename) {
RExplorer::url_redirect('?view=rename&path=' . $path, 2, '名称不能为空!');
}
$sapath = RexHelper::path_rtoa($path);
if (is_file($sapath) && strpos($filename, '.') === false) {
RExplorer::url_redirect('?view=rename&path=' . $path, 2, '文件扩展名无效!');
}
$target = dirname($sapath) . DIRECTORY_SEPARATOR . $filename;
if (@rename($sapath, $target)) {
RExplorer::url_redirect('?path=' . dirname($path), 1);
}
RExplorer::url_redirect('?path=' . dirname($path), 2);
}
/**
* 编辑权限
* @param string $path 路径
*/
static function act_chmod($path)
{
$mode = intval(G('mode'), 8);
if (!$mode) {
RExplorer::url_redirect('?view=chmod&path=' . $path, 2, '权限模式无效!');
}
$sapath = RexHelper::path_rtoa($path);
if (@chmod($sapath, $mode)) {
RExplorer::url_redirect('?path=' . dirname($path), 1);
}
RExplorer::url_redirect('?path=' . dirname($path), 2);
}
/**
* 压缩操作
* @param string $path 路径
*/
static function act_zip($path)
{
$filename = G('filename');
if (!$filename || !strpos($filename, '.')) {
RExplorer::url_redirect('?path=' . $path, 2, '压缩文件名无效!');
}
$filename = RexHelper::path_rtoa($filename);
if (file_exists($filename)) {
RExplorer::url_redirect('?path=' . $path, 2, '压缩文件已存在!');
}
$content = G('content');
if (!$content) {
RExplorer::url_redirect('?path=' . $path, 2, '压缩内容无效!');
}
$include = array();
$exclude = array();
$items = explode(PHP_EOL, $content);
foreach ($items as $item) {
if (strpos($item, 'exclude ') === 0) {
$exclude[] = RexHelper::path_rtoa(trim(substr($item, 8)));
} else {
$include[] = RexHelper::path_rtoa($item);
}
}
if (empty($include)) {
RExplorer::url_redirect('?path=' . $path, 2, '压缩内容无效!');
}
$zip = new ZipHelper();
$trimpath = RexHelper::path_rtoa(G('trimpath'));
if ($zip->zip($filename, $msg, $include, $exclude, $trimpath)) {
RExplorer::url_redirect('?path=' . $path, 1, $msg);
}
RExplorer::url_redirect('?path=' . $path, 2, $msg);
}
/**
* 解压缩文件
* @param string $path 路径
*/
static function act_unzip($path)
{
$root = RexHelper::path_rtoa(G('root'));
$filename = RexHelper::path_rtoa(G('filename'));
if (!$filename) {
$msg = '压缩文件路径无效!';
RExplorer::url_redirect('?path=' . $path, 2, $msg);
}
if (!$root) {
$msg = '解压缩路径无效!';
RExplorer::url_redirect('?path=' . $path, 2, $msg);
}
$zip = new ZipHelper();
if ($zip->unzip($filename, $root, $msg)) {
RExplorer::url_redirect('?path=' . $path, 1, $msg);
}
RExplorer::url_redirect('?path=' . $path, 2, $msg);
}
/**
* 清空OPCache
* @param string $path 路径
*/
static function act_opreset($path)
{
if (opcache_reset()) {
RExplorer::url_redirect('?path=' . $path, 1);
}
RExplorer::url_redirect('?path=' . $path, 2);
}
}
class RexHelper
{
static $root = __DIR__;
static $version = '1.4';
static $ssid = 'rexplorer_sid';
static $users = array();
static $text_suff = array(
'sql', 'tpl', 'php', 'htm', 'html', 'ts', 'js', 'css',
'bat', 'sh', 'md', 'log', 'txt', 'json', 'env', 'ini',
);
static $img_suff = array(
'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'ico', 'jfif',
'tif', 'tga', 'svg'
);
static $ignore_list = array();
/**
* 优化容量显示
* @param string $path 路径
*/
static function format_bytes($size)
{
$units = array(' B', ' KB', ' MB', ' GB', ' TB');
for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024;
return round($size, 2) . $units[$i];
}
/**
* 绝对路径转相对路径
* @param string $path 路径
* @return string
*/
static function path_ator($path)
{
$path = substr($path, strlen(self::$root));
if (DIRECTORY_SEPARATOR != '/') {
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
}
return $path;
}
/**
* 相对路径转绝对路径
* @param string $path 路径
* @return string
*/
static function path_rtoa($path)
{
$path = self::$root . DIRECTORY_SEPARATOR . trim($path, '/\\');
if (DIRECTORY_SEPARATOR != '/') {
return str_replace('/', DIRECTORY_SEPARATOR, $path);
}
return $path;
}
/**
* 获取文件扩展名类型
* @param string $path 文件路径
* @return string
*/
static function file_catetory($path)
{
if ($ext = pathinfo($path, PATHINFO_EXTENSION)) {
if (in_array($ext, self::$text_suff)) {
return 'text';
}
if (in_array($ext, self::$img_suff)) {
return 'image';
}
}
return '';
}
/**
* 检测是否需要排除
* @param string $name 文件名称
* @return string
*/
static function is_ignore($name)
{
if (!empty(self::$ignore_list)) {
foreach (self::$ignore_list as $expr) {
if (preg_match($expr, $name)) {
return true;
}
}
}
return false;
}
}
/**
* 压缩类
*/
class ZipHelper
{
/**
* 解压缩之
* @param string $filename 文件名
* @param string $path 解压路径
* @param string $msg 错误消息
* @return boolean
*/
function unzip($filename, $path, &$msg = '')
{
if (!$filename) {
$msg = '压缩文件名无效!';
return false;
}
$zip = new ZipArchive();
$msg = $zip->open($filename);
if (true !== $msg) {
$msg = var_export($msg, true);
return false;
}
$zip->extractTo($path);
$zip->close();
return true;
}
/**
* 压缩之
* @param string $filename 文件名
* @param string $msg 错误消息
* @param array $include 包含文件列表
* @param array $exclude 排除文件列表
* @param string $trimpath 删除根路径
* @param string $comment 注释内容
* @return boolean
*/
function zip($filename, &$msg = '', $include = array(), $exclude = array(), $trimpath = '', $comment = 'default')
{
if (!$filename) {
$msg = '压缩文件名无效!';
return false;
}
if (empty($include)) {
$msg = '压缩内容无效!';
return false;
}
if ('default' == $comment) {
$comment = basename($filename) . PHP_EOL . 'Generate at ' . date('Y-m-d H:i:s') . PHP_EOL . 'Powerd by RExplorer.';
}
try {
$zip = new ZipArchive();
$res = $zip->open($filename, ZipArchive::CREATE);
if ($res !== true) {
$msg = var_export($res, true);
return false;
}
if ($comment) {
$zip->setArchiveComment($comment);
}
if ($trimpath) {
$trimpath = rtrim($trimpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
}
$substart = strlen($trimpath);
foreach ($include as $source) {
$this->zip_dir($zip, $source, $exclude, $substart);
}
$zip->close();
return true;
} catch (Exception $ex) {
$msg = $ex->getMessage();
return false;
}
}
/**
* 递归压缩整个目录
* @param ZipArchive $zip Zip 实例
* @param string $source 包含的路径
* @param array $exclude 排除的路径
* @param int $substart 开始截取的路径字符串(用于去除路径中的根目录路径)
*/
function zip_dir(&$zip, $source, $exclude, $substart = 0)
{
if (is_dir($source)) {
$source = rtrim($source, DIRECTORY_SEPARATOR);
if ($handle = opendir($source)) {
while (false !== ($f = readdir($handle))) {
if ('.' == $f || '..' == $f) {
continue;
}
$filename = $source . DIRECTORY_SEPARATOR . $f;
if (is_dir($filename)) {
if ($exclude && in_array($filename, $exclude)) {
continue;
}
$this->zip_dir($zip, $filename, $exclude, $substart);
} else {
if ($exclude && in_array($filename, $exclude)) {
continue;
}
$zip->addFile($filename, substr($filename, $substart));
}
}
closedir($handle);
}
} else {
if ($exclude && in_array($source, $exclude)) {
return;
}
$zip->addFile($source);
}
}
}
/** 环境检测 */
require_once APP_ROOT . '/app/check.php';
/** 底部广告 */
if ($config['ad_bot']) echo $config['ad_bot_info'];
/** 引入底部 */
require_once APP_ROOT . '/app/footer.php';