490 lines
14 KiB
PHP
490 lines
14 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @package FF Explorer
|
|
* @subpackage com_ffexplorer
|
|
*
|
|
* @copyright https://github.com/trananhmanh89/ffexplorer
|
|
* @license MIT
|
|
*/
|
|
|
|
use Joomla\Archive\Archive;
|
|
use Joomla\Archive\Zip;
|
|
use Joomla\CMS\Filesystem\File;
|
|
use Joomla\CMS\Filesystem\Folder;
|
|
use Joomla\CMS\Filesystem\Path;
|
|
use Joomla\CMS\Helper\MediaHelper;
|
|
use Joomla\CMS\MVC\Controller\BaseController;
|
|
use Joomla\CMS\String\PunycodeHelper;
|
|
|
|
defined('_JEXEC') or die('Restricted access');
|
|
|
|
class FfexplorerControllerExplorer extends BaseController
|
|
{
|
|
public function extract()
|
|
{
|
|
$this->checkToken();
|
|
|
|
$target = $this->input->get('target', '', 'raw');
|
|
$source = $this->input->get('source', '', 'raw');
|
|
|
|
if (!$target || !$source) {
|
|
$this->response('error', 'Path not found');
|
|
}
|
|
|
|
$target = JPATH_ROOT . $target;
|
|
$source = JPATH_ROOT . $source;
|
|
if (!is_file($source) || !is_dir($target)) {
|
|
$this->response('error', 'Path not found');
|
|
}
|
|
|
|
try {
|
|
$archive = new Archive();
|
|
$archive->extract($source, $target);
|
|
|
|
$this->response('success', true);
|
|
} catch (Exception $e) {
|
|
$this->response('error', $e->getMessage());
|
|
}
|
|
}
|
|
public function download()
|
|
{
|
|
$this->checkToken();
|
|
$relativePath = $this->input->getString('path');
|
|
$path = realpath(JPATH_ROOT . $relativePath);
|
|
|
|
if (!$relativePath || !file_exists($path) || !is_file($path)) {
|
|
$this->response('error', 'File not existed');
|
|
}
|
|
|
|
ob_clean();
|
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
|
|
|
header('Content-Type: ' . finfo_file($finfo, $path));
|
|
|
|
$finfo = finfo_open(FILEINFO_MIME_ENCODING);
|
|
header('Content-Transfer-Encoding: ' . finfo_file($finfo, $path));
|
|
|
|
header('Content-disposition: attachment; filename="' . basename($path) . '"');
|
|
|
|
readfile($path);
|
|
die();
|
|
}
|
|
|
|
public function compress()
|
|
{
|
|
$this->checkToken();
|
|
$relativePath = $this->input->getString('path');
|
|
$path = realpath(JPATH_ROOT . $relativePath);
|
|
|
|
if (!$relativePath || !file_exists($path)) {
|
|
$this->response('error', 'Path not existed');
|
|
}
|
|
|
|
$info = pathinfo($path);
|
|
$items = array();
|
|
|
|
if (is_dir($path)) {
|
|
$exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX');
|
|
$excludefilter = array('.*~');
|
|
$files = Folder::files($path, '.', true, true, $exclude, $excludefilter);
|
|
|
|
foreach ($files as &$file) {
|
|
$content = array();
|
|
$content['data'] = file_get_contents($file);
|
|
|
|
$name = realpath($file);
|
|
$name = $info['filename'] . str_replace($path, '', $name);
|
|
$content['name'] = $name;
|
|
$items[] = $content;
|
|
}
|
|
|
|
} else {
|
|
$items[] = array(
|
|
'data' => file_get_contents($path),
|
|
'name' => $info['basename']
|
|
);
|
|
}
|
|
|
|
$target = $info['dirname'] . '/' . $info['filename'] . '.zip';
|
|
if (File::exists($target)) {
|
|
for ($i=1; $i < 100; $i++) {
|
|
$target = $info['dirname'] . '/' . $info['filename'] . '(' . $i . ')' . '.zip';
|
|
if (!File::exists($target)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$archive = new Zip();
|
|
$result = $archive->create($target, $items);
|
|
|
|
if ($result) {
|
|
$this->response('success', '');
|
|
} else {
|
|
$this->response('error', 'Compress error!!');
|
|
}
|
|
}
|
|
|
|
public function getPermission()
|
|
{
|
|
$this->checkToken();
|
|
$relativePath = $this->input->getString('path');
|
|
$path = realpath(JPATH_ROOT . $relativePath);
|
|
|
|
if (!$relativePath || !file_exists($path)) {
|
|
$this->response('error', 'Path not existed');
|
|
}
|
|
|
|
if (!Path::check($path)) {
|
|
$this->response('error', 'Path error');
|
|
}
|
|
|
|
$permission = Path::getPermissions($path);
|
|
$this->response('permission', $permission);
|
|
}
|
|
|
|
public function setPermission()
|
|
{
|
|
$this->checkToken();
|
|
$relativePath = $this->input->getString('path');
|
|
$path = realpath(JPATH_ROOT . $relativePath);
|
|
|
|
if (!$relativePath || !file_exists($path)) {
|
|
$this->response('error', 'Path not existed');
|
|
}
|
|
|
|
$mode = $this->input->get('mode');
|
|
if (!$mode) {
|
|
$this->response('error', 'Mode is missing!');
|
|
}
|
|
|
|
if (is_dir($path)) {
|
|
$result = Path::setPermissions($path, null, $mode);
|
|
} else {
|
|
$result = Path::setPermissions($path, $mode, null);
|
|
}
|
|
|
|
if ($result) {
|
|
$this->response('success', '');
|
|
} else {
|
|
$this->response('error', 'Set permission failed');
|
|
}
|
|
}
|
|
|
|
public function upload()
|
|
{
|
|
$this->checkToken();
|
|
$path = $this->input->getString('path');
|
|
$path = Path::clean($path, '/');
|
|
if (!is_dir(JPATH_ROOT . $path)) {
|
|
$this->response('error', 'empty path');
|
|
}
|
|
|
|
$path = $path ? $path : '/';
|
|
|
|
$file = $this->input->files->get('file', array(), 'raw');
|
|
$contentLength = (int) $file['size'];
|
|
$mediaHelper = new MediaHelper;
|
|
$postMaxSize = $mediaHelper->toBytes(ini_get('post_max_size'));
|
|
$memoryLimit = $mediaHelper->toBytes(ini_get('memory_limit'));
|
|
$uploadMaxFileSize = $mediaHelper->toBytes(ini_get('upload_max_filesize'));
|
|
|
|
if (($file['error'] == 1)
|
|
|| ($postMaxSize > 0 && $contentLength > $postMaxSize)
|
|
|| ($memoryLimit != -1 && $contentLength > $memoryLimit)
|
|
|| ($uploadMaxFileSize > 0 && $contentLength > $uploadMaxFileSize))
|
|
{
|
|
$this->response('error', 'File too large');
|
|
}
|
|
|
|
$file['filepath'] = JPATH_ROOT . $path . '/' . $file['name'];
|
|
|
|
if (File::exists($file['filepath']))
|
|
{
|
|
$this->response('error', 'File ' . $file['name'] . ' existed');
|
|
}
|
|
|
|
if (!isset($file['name']))
|
|
{
|
|
$this->response('error', 'File error');
|
|
}
|
|
|
|
if (File::upload($file['tmp_name'], $file['filepath'], false, true)) {
|
|
$this->response('success', '');
|
|
} else {
|
|
$this->response('error', 'Upload error');
|
|
}
|
|
}
|
|
|
|
public function saveContent()
|
|
{
|
|
$this->checkToken();
|
|
$path = $this->input->getString('path');
|
|
$path = Path::clean($path, '/');
|
|
$content = $this->input->get('content', '', 'raw');
|
|
|
|
if (!$path) {
|
|
$this->response('error', 'empty path');
|
|
}
|
|
|
|
$file = JPATH_ROOT . $path;
|
|
if (!File::exists($file)) {
|
|
$this->response('error', 'file not existed');
|
|
}
|
|
|
|
if (@File::write($file, $content)) {
|
|
$this->response('success', 'saved');
|
|
} else {
|
|
$this->response('error', 'could not write file');
|
|
}
|
|
}
|
|
|
|
public function openFile()
|
|
{
|
|
$this->checkToken();
|
|
|
|
$path = $this->input->getString('path');
|
|
$path = Path::clean($path, '/');
|
|
if (!$path) {
|
|
$this->response('error', 'empty path');
|
|
}
|
|
|
|
$file = JPATH_ROOT . $path;
|
|
if (!File::exists($file)) {
|
|
$this->response('error', 'file not existed');
|
|
}
|
|
|
|
$mime = mime_content_type($file);
|
|
if (strpos($mime, 'text') === 0 || $mime === 'inode/x-empty') {
|
|
$content = file_get_contents($file);
|
|
$this->response('content', $content);
|
|
} else {
|
|
$this->response('error', 'Could not open this file');
|
|
}
|
|
}
|
|
|
|
public function explodeFolder()
|
|
{
|
|
$this->checkToken();
|
|
|
|
$path = $this->input->getString('path');
|
|
|
|
$path = $path ? JPATH_ROOT . $path : JPATH_ROOT;
|
|
$folders = Folder::folders($path, '.', false, true);
|
|
$folders = array_map(function($folder) {
|
|
$folder = realpath($folder);
|
|
$info = pathinfo($folder);
|
|
|
|
$item = new stdClass;
|
|
$item->path = str_replace(JPATH_ROOT, '', $folder);
|
|
$item->name = $info['basename'];
|
|
$item->type = 'folder';
|
|
|
|
return $item;
|
|
}, $folders);
|
|
|
|
$exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX');
|
|
$excludefilter = array('.*~');
|
|
$files = Folder::files($path, '.', false, true, $exclude, $excludefilter);
|
|
$files = array_map(function($file) {
|
|
$file = realpath($file);
|
|
$info = pathinfo($file);
|
|
|
|
$item = new stdClass;
|
|
$item->path = str_replace(JPATH_ROOT, '', $file);
|
|
$item->name = $info['basename'];
|
|
$item->type = 'file';
|
|
|
|
return $item;
|
|
}, $files);
|
|
|
|
$result = array_merge($folders, $files);
|
|
|
|
die(json_encode($result));
|
|
}
|
|
|
|
public function newFile()
|
|
{
|
|
$this->checkToken();
|
|
|
|
$name = $this->input->getString('name');
|
|
$path = $this->input->getString('path');
|
|
|
|
if (!$name || !$path) {
|
|
die(json_encode(array('error' => 'empty')));
|
|
}
|
|
|
|
$file = JPATH_ROOT . $path . '/' . $name;
|
|
if (File::exists($file)) {
|
|
$this->response('error', 'File is already existed');
|
|
}
|
|
|
|
if (File::write($file, '')) {
|
|
$this->response('success', 'File has been created');
|
|
} else {
|
|
$this->response('error', 'Create file failed');
|
|
}
|
|
}
|
|
|
|
public function newFolder()
|
|
{
|
|
$this->checkToken();
|
|
|
|
$name = $this->input->getString('name');
|
|
$path = $this->input->getString('path');
|
|
|
|
$name = Folder::makeSafe($name);
|
|
|
|
if (!$name || !$path) {
|
|
die(json_encode(array('error' => 'empty')));
|
|
}
|
|
|
|
$folder = JPATH_ROOT . $path . '/' . $name;
|
|
if (Folder::exists($folder)) {
|
|
$this->response('error', 'Folder is already existed');
|
|
}
|
|
|
|
if (Folder::create($folder)) {
|
|
$this->response('success', 'Folder has been created');
|
|
} else {
|
|
$this->response('error', 'Create folder failed');
|
|
}
|
|
}
|
|
|
|
public function renameFolder()
|
|
{
|
|
$this->checkToken();
|
|
|
|
$newName = $this->input->getString('newName');
|
|
$oldPath = $this->input->getString('oldPath');
|
|
|
|
$newName = Folder::makeSafe($newName);
|
|
|
|
if (!$newName || !$oldPath) {
|
|
$this->response('error', 'empty');
|
|
}
|
|
|
|
if (!Folder::exists(JPATH_ROOT . $oldPath)) {
|
|
$this->response('error', 'Folder not found');
|
|
}
|
|
|
|
$info = pathinfo($oldPath);
|
|
$folder = JPATH_ROOT . $info['dirname'] . '/' . $newName;
|
|
if (Folder::exists($folder)) {
|
|
$this->response('error', 'Folder is already existed');
|
|
}
|
|
|
|
$result = rename( JPATH_ROOT . $oldPath, $folder);
|
|
if ($result) {
|
|
$folderPath = realpath($folder);
|
|
$folderPath = str_replace(JPATH_ROOT, '', $folderPath);
|
|
|
|
$this->response('data', array(
|
|
'path' => $folderPath,
|
|
'name' => $newName,
|
|
));
|
|
} else {
|
|
$this->response('error', 'rename error');
|
|
}
|
|
}
|
|
|
|
public function deleteFolder()
|
|
{
|
|
$this->checkToken();
|
|
|
|
$path = $this->input->getString('path');
|
|
$path = Path::clean($path, '/');
|
|
if (!$path) {
|
|
$this->response('error', 'empty path');
|
|
}
|
|
|
|
if (Folder::exists(JPATH_ROOT . $path)) {
|
|
try {
|
|
if(Folder::delete(JPATH_ROOT . $path)) {
|
|
$this->response('success', 'deleted');
|
|
} else {
|
|
$this->response('error', 'Delete failed');
|
|
}
|
|
} catch (Exception $e) {
|
|
$this->response('error', $e->getMessage());
|
|
}
|
|
|
|
} else {
|
|
$this->response('error', 'Folder is not existed');
|
|
}
|
|
}
|
|
|
|
public function renameFile()
|
|
{
|
|
$this->checkToken();
|
|
|
|
$newName = $this->input->getString('newName');
|
|
$oldPath = $this->input->getString('oldPath');
|
|
|
|
if (!$newName || !$oldPath) {
|
|
$this->response('error', 'empty');
|
|
}
|
|
|
|
if (!File::exists(JPATH_ROOT . $oldPath)) {
|
|
$this->response('error', 'File not found');
|
|
}
|
|
|
|
$info = pathinfo($oldPath);
|
|
$file = JPATH_ROOT . $info['dirname'] . '/' . $newName;
|
|
if (File::exists($file)) {
|
|
$this->response('error', 'File is already existed');
|
|
}
|
|
|
|
$result = rename( JPATH_ROOT . $oldPath, $file);
|
|
if ($result) {
|
|
$filePath = realpath($file);
|
|
$filePath = str_replace(JPATH_ROOT, '', $filePath);
|
|
|
|
$this->response('data', array(
|
|
'path' => $filePath,
|
|
'name' => $newName,
|
|
));
|
|
} else {
|
|
$this->response('error', 'rename error');
|
|
}
|
|
}
|
|
|
|
public function deleteFile()
|
|
{
|
|
$this->checkToken();
|
|
|
|
$path = $this->input->getString('path');
|
|
$path = Path::clean($path, '/');
|
|
if (!$path) {
|
|
$this->response('error', 'empty path');
|
|
}
|
|
|
|
if (File::exists(JPATH_ROOT . $path)) {
|
|
try {
|
|
if(File::delete(JPATH_ROOT . $path)) {
|
|
$this->response('success', 'deleted');
|
|
} else {
|
|
$this->response('error', 'Delete failed');
|
|
}
|
|
} catch (Exception $e) {
|
|
$this->response('error', $e->getMessage());
|
|
}
|
|
} else {
|
|
$this->response('error', 'File is not existed');
|
|
}
|
|
}
|
|
|
|
public function checkToken($method = 'post', $redirect = false)
|
|
{
|
|
// sleep(3);
|
|
if (!parent::checkToken($method, $redirect)) {
|
|
$this->response('error', 'csrf token error');
|
|
}
|
|
}
|
|
|
|
protected function response($type = 'success', $data = array())
|
|
{
|
|
die(@json_encode(array($type => $data)));
|
|
}
|
|
} |