/server/fs.ajax.php
PHP | 267 lines | 207 code | 11 blank | 49 comment | 51 complexity | a362e2157ef16b486dba169217b77c79 MD5 | raw file
- <?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();
- }