1
0
Fork 0
mirror of https://github.com/Yetangitu/ampache synced 2025-10-03 09:49:30 +02:00
ampache/server/fs.ajax.php
Lawrence Brown 60a653daf4 copyright 2014 -> 2015
janitorial services
2015-01-04 21:36:41 +00:00

267 lines
9.8 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
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
/**
*
* LICENSE: GNU General Public License, version 2 (GPLv2)
* Copyright 2001 - 2015 Ampache.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License v2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
// jsTree file system browser
define('AJAX_INCLUDE','1');
require_once '../lib/init.php';
$rootdir = Upload::get_root();
if (empty($rootdir)) {
exit;
}
$rootdir .= DIRECTORY_SEPARATOR;
ini_set('open_basedir', $rootdir);
class fs
{
protected $base = null;
protected function real($path)
{
$temp = realpath($path);
if (!$temp) { throw new Exception('Path does not exist: ' . $path); }
if ($this->base && strlen($this->base)) {
if (strpos($temp, $this->base) !== 0) { throw new Exception('Path is not inside base ('.$this->base.'): ' . $temp); }
}
return $temp;
}
protected function path($id)
{
$id = str_replace('/', DIRECTORY_SEPARATOR, $id);
$id = trim($id, DIRECTORY_SEPARATOR);
$id = $this->real($this->base . DIRECTORY_SEPARATOR . $id);
return $id;
}
protected function id($path)
{
$path = $this->real($path);
$path = substr($path, strlen($this->base));
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
$path = trim($path, '/');
return strlen($path) ? $path : '/';
}
public function __construct($base)
{
$this->base = $this->real($base);
if (!$this->base) { throw new Exception('Base directory does not exist'); }
}
public function lst($id, $with_root = false)
{
$dir = $this->path($id);
$lst = @scandir($dir);
if (!$lst) { throw new Exception('Could not list path: ' . $dir); }
$res = array();
foreach ($lst as $item) {
if ($item == '.' || $item == '..' || $item === null) { continue; }
$tmp = preg_match('([^ a-zа-я-_0-9.]+)ui', $item);
if ($tmp === false || $tmp === 1) { continue; }
if (is_dir($dir . DIRECTORY_SEPARATOR . $item)) {
$res[] = array('text' => $item, 'children' => true, 'id' => $this->id($dir . DIRECTORY_SEPARATOR . $item), 'icon' => 'folder');
} else {
//$res[] = array('text' => $item, 'children' => false, 'id' => $this->id($dir . DIRECTORY_SEPARATOR . $item), 'type' => 'file', 'icon' => 'file file-'.substr($item, strrpos($item,'.') + 1));
}
}
if ($with_root && $this->id($dir) === '/') {
$res = array(array('text' => basename($this->base), 'children' => $res, 'id' => '/', 'icon'=>'folder', 'state' => array('opened' => true, 'disabled' => true)));
}
return $res;
}
public function data($id)
{
if (strpos($id, ":")) {
$id = array_map(array($this, 'id'), explode(':', $id));
return array('type'=>'multiple', 'content'=> 'Multiple selected: ' . implode(' ', $id));
}
$dir = $this->path($id);
if (is_dir($dir)) {
return array('type'=>'folder', 'content'=> $id);
}
if (is_file($dir)) {
$ext = strpos($dir, '.') !== FALSE ? substr($dir, strrpos($dir, '.') + 1) : '';
$dat = array('type' => $ext, 'content' => '');
switch ($ext) {
/*case 'txt':
case 'text':
case 'md':
case 'js':
case 'json':
case 'css':
case 'html':
case 'htm':
case 'xml':
case 'c':
case 'cpp':
case 'h':
case 'sql':
case 'log':
case 'py':
case 'rb':
case 'htaccess':
case 'php':
$dat['content'] = file_get_contents($dir);
break;
case 'jpg':
case 'jpeg':
case 'gif':
case 'png':
case 'bmp':
$dat['content'] = 'data:'.finfo_file(finfo_open(FILEINFO_MIME_TYPE), $dir).';base64,'.base64_encode(file_get_contents($dir));
break;*/
default:
$dat['content'] = 'File not recognized: '.$this->id($dir);
break;
}
return $dat;
}
throw new Exception('Not a valid selection: ' . $dir);
}
public function create($id, $name, $mkdir = false)
{
$dir = $this->path($id);
if (preg_match('([^ a-zа-я-_0-9.]+)ui', $name) || !strlen($name)) {
throw new Exception('Invalid name: ' . $name);
}
if ($mkdir) {
mkdir($dir . DIRECTORY_SEPARATOR . $name);
} else {
file_put_contents($dir . DIRECTORY_SEPARATOR . $name, '');
}
return array('id' => $this->id($dir . DIRECTORY_SEPARATOR . $name));
}
public function rename($id, $name)
{
$dir = $this->path($id);
if ($dir === $this->base) {
throw new Exception('Cannot rename root');
}
if (preg_match('([^ a-zа-я-_0-9.]+)ui', $name) || !strlen($name)) {
throw new Exception('Invalid name: ' . $name);
}
$new = explode(DIRECTORY_SEPARATOR, $dir);
array_pop($new);
array_push($new, $name);
$new = implode(DIRECTORY_SEPARATOR, $new);
if (is_file($new) || is_dir($new)) { throw new Exception('Path already exists: ' . $new); }
rename($dir, $new);
return array('id' => $this->id($new));
}
public function remove($id)
{
$dir = $this->path($id);
if ($dir === $this->base) {
throw new Exception('Cannot remove root');
}
if (is_dir($dir)) {
foreach (array_diff(scandir($dir), array(".", "..")) as $f) {
$this->remove($this->id($dir . DIRECTORY_SEPARATOR . $f));
}
rmdir($dir);
}
if (is_file($dir)) {
unlink($dir);
}
return array('status' => 'OK');
}
public function move($id, $par)
{
$dir = $this->path($id);
$par = $this->path($par);
$new = explode(DIRECTORY_SEPARATOR, $dir);
$new = array_pop($new);
$new = $par . DIRECTORY_SEPARATOR . $new;
rename($dir, $new);
return array('id' => $this->id($new));
}
public function copy($id, $par)
{
$dir = $this->path($id);
$par = $this->path($par);
$new = explode(DIRECTORY_SEPARATOR, $dir);
$new = array_pop($new);
$new = $par . DIRECTORY_SEPARATOR . $new;
if (is_file($new) || is_dir($new)) { throw new Exception('Path already exists: ' . $new); }
if (is_dir($dir)) {
mkdir($new);
foreach (array_diff(scandir($dir), array(".", "..")) as $f) {
$this->copy($this->id($dir . DIRECTORY_SEPARATOR . $f), $this->id($new));
}
}
if (is_file($dir)) {
copy($dir, $new);
}
return array('id' => $this->id($new));
}
}
if (isset($_GET['operation'])) {
$fs = new fs($rootdir);
try {
$rslt = null;
switch ($_GET['operation']) {
case 'get_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->lst($node, (isset($_GET['id']) && $_GET['id'] === '#'));
break;
case "get_content":
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->data($node);
break;
case 'create_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->create($node, isset($_GET['text']) ? $_GET['text'] : '', (!isset($_GET['type']) || $_GET['type'] !== 'file'));
break;
case 'rename_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->rename($node, isset($_GET['text']) ? $_GET['text'] : '');
break;
case 'delete_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->remove($node);
break;
case 'move_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$parn = isset($_GET['parent']) && $_GET['parent'] !== '#' ? $_GET['parent'] : '/';
$rslt = $fs->move($node, $parn);
break;
case 'copy_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$parn = isset($_GET['parent']) && $_GET['parent'] !== '#' ? $_GET['parent'] : '/';
$rslt = $fs->copy($node, $parn);
break;
default:
throw new Exception('Unsupported operation: ' . $_GET['operation']);
}
header('Content-Type: application/json; charset=utf8');
echo json_encode($rslt);
} catch (Exception $e) {
header($_SERVER["SERVER_PROTOCOL"] . ' 500 Server Error');
header('Status: 500 Server Error');
echo $e->getMessage();
}
die();
}