<?php
 class elFinderConnector {
 protected $elFinder;
 protected $options = array();
 protected $header = '';
 protected $reqMethod = '';
 protected static $contentType = 'Content-Type: application/json; charset=utf-8';
 public function __construct($elFinder, $debug = false) {
 $this->elFinder = $elFinder;
 $this->reqMethod = strtoupper($_SERVER["REQUEST_METHOD"]);
 if ($debug) {
 self::$contentType = 'Content-Type: text/plain; charset=utf-8';
 }
 }
 public function run() {
 $isPost = $this->reqMethod === 'POST';
 $src = $isPost ? array_merge($_GET, $_POST) : $_GET;
 $maxInputVars = (!$src || isset($src['targets'])) ? ini_get('max_input_vars') : null;
 if ((!$src || $maxInputVars) && $rawPostData = file_get_contents('php://input')) {
 $parts = explode('&', $rawPostData);
 if (!$src || $maxInputVars < count($parts)) {
 $src = array();
 foreach ($parts as $part) {
 list($key, $value) = array_pad(explode('=', $part), 2, '');
 $key = rawurldecode($key);
 if (preg_match('/^(.+?)\[([^\[\]]*)\]$/', $key, $m)) {
 $key = $m[1];
 $idx = $m[2];
 if (!isset($src[$key])) {
 $src[$key] = array();
 }
 if ($idx) {
 $src[$key][$idx] = rawurldecode($value);
 }
 else {
 $src[$key][] = rawurldecode($value);
 }
 }
 else {
 $src[$key] = rawurldecode($value);
 }
 }
 $_POST = $this->input_filter($src);
 $_REQUEST = $this->input_filter(array_merge_recursive($src, $_REQUEST));
 }
 }
 if (isset($src['targets']) && $this->elFinder->maxTargets && count($src['targets']) > $this->elFinder->maxTargets) {
 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_MAX_TARGTES)));
 }
 $cmd = isset($src['cmd']) ? $src['cmd'] : '';
 $args = array();
 if (!function_exists('json_encode')) {
 $error = $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_JSON);
 $this->output(array('error' => '{"error":["' . implode('","', $error) . '"]}', 'raw' => true));
 }
 if (!$this->elFinder->loaded()) {
 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_VOL), 'debug' => $this->elFinder->mountErrors));
 }
 if (!$cmd && $isPost) {
 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UPLOAD, elFinder::ERROR_UPLOAD_TOTAL_SIZE), 'header' => 'Content-Type: text/html'));
 }
 if (!$this->elFinder->commandExists($cmd)) {
 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UNKNOWN_CMD)));
 }
 $hasFiles = false;
 foreach ($this->elFinder->commandArgsList($cmd) as $name => $req) {
 if ($name === 'FILES') {
 if (isset($_FILES)) {
 $hasFiles = true;
 }
 elseif ($req) {
 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
 }
 }
 else {
 $arg = isset($src[$name]) ? $src[$name] : '';
 if (!is_array($arg) && $req !== '') {
 $arg = trim($arg);
 }
 if ($req && $arg === '') {
 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
 }
 $args[$name] = $arg;
 }
 }
 $args['debug'] = isset($src['debug']) ? !!$src['debug'] : false;
 $args = $this->input_filter($args);
 if ($hasFiles) {
 $args['FILES'] = $_FILES;
 }
 try {
 $this->output($this->elFinder->exec($cmd, $args));
 }
 catch (elFinderAbortException $e) {
 $this->elFinder->getSession()->close();
 header('HTTP/1.0 204 No Content');
 while (ob_get_level() && ob_end_clean()) {
 }
 exit();
 }
 }
 protected function output(array $data) {
 $this->elFinder->getSession()->close();
 ignore_user_abort(false);
 if ($this->header) {
 self::sendHeader($this->header);
 }
 if (isset($data['pointer'])) {
 elFinder::extendTimeLimit(0);
 if (!empty($data['header'])) {
 self::sendHeader($data['header']);
 }
 while (ob_get_level() && ob_end_clean()) {
 }
 $toEnd = true;
 $fp = $data['pointer'];
 $sendData = !($this->reqMethod === 'HEAD' || !empty($data['info']['xsendfile']));
 $psize = null;
 if (($this->reqMethod === 'GET' || !$sendData) && elFinder::isSeekableStream($fp) && (array_search('Accept-Ranges: none', headers_list()) === false)) {
 header('Accept-Ranges: bytes');
 if (!empty($_SERVER['HTTP_RANGE'])) {
 $size = $data['info']['size'];
 $end = $size - 1;
 if (preg_match('/bytes=(\d*)-(\d*)(,?)/i', $_SERVER['HTTP_RANGE'], $matches)) {
 if (empty($matches[3])) {
 if (empty($matches[1]) && $matches[1] !== '0') {
 $start = $size - $matches[2];
 }
 else {
 $start = intval($matches[1]);
 if (!empty($matches[2])) {
 $end = intval($matches[2]);
 if ($end >= $size) {
 $end = $size - 1;
 }
 $toEnd = ($end == ($size - 1));
 }
 }
 $psize = $end - $start + 1;
 header('HTTP/1.1 206 Partial Content');
 header('Content-Length: ' . $psize);
 header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size);
 if (isset($data['info']['xsendfile']) && strtolower($data['info']['xsendfile']) === 'x-sendfile') {
 if (function_exists('header_remove')) {
 header_remove($data['info']['xsendfile']);
 }
 else {
 header($data['info']['xsendfile'] . ':');
 }
 unset($data['info']['xsendfile']);
 if ($this->reqMethod !== 'HEAD') {
 $sendData = true;
 }
 }
 $sendData && fseek($fp, $start);
 }
 }
 }
 if ($sendData && is_null($psize)) {
 elFinder::rewind($fp);
 }
 }
 else {
 header('Accept-Ranges: none');
 if (isset($data['info']) && !$data['info']['size']) {
 if (function_exists('header_remove')) {
 header_remove('Content-Length');
 }
 else {
 header('Content-Length:');
 }
 }
 }
 if ($sendData) {
 if ($toEnd) {
 if (version_compare(PHP_VERSION, '5.6', '<')) {
 file_put_contents('php://output', $fp);
 }
 else {
 fpassthru($fp);
 }
 }
 else {
 $out = fopen('php://output', 'wb');
 stream_copy_to_stream($fp, $out, $psize);
 fclose($out);
 }
 }
 if (!empty($data['volume'])) {
 $data['volume']->close($data['pointer'], $data['info']['hash']);
 }
 exit();
 }
 else {
 self::outputJson($data);
 exit(0);
 }
 }
 protected function input_filter($args) {
 static $magic_quotes_gpc = NULL;
 if ($magic_quotes_gpc === NULL) $magic_quotes_gpc = (version_compare(PHP_VERSION, '5.4', '<') && get_magic_quotes_gpc());
 if (is_array($args)) {
 return array_map(array(& $this, 'input_filter'), $args);
 }
 $res = str_replace("\0", '', $args);
 $magic_quotes_gpc && ($res = stripslashes($res));
 return $res;
 }
 protected static function sendHeader($header = null) {
 if ($header) {
 if (is_array($header)) {
 foreach ($header as $h) {
 header($h);
 }
 }
 else {
 header($header);
 }
 }
 }
 public static function outputJson($data) {
 $header = isset($data['header']) ? $data['header'] : self::$contentType;
 self::sendHeader($header);
 unset($data['header']);
 if (!empty($data['raw']) && isset($data['error'])) {
 $out = $data['error'];
 }
 else {
 if (isset($data['debug']) && isset($data['debug']['phpErrors'])) {
 $data['debug']['phpErrors'] = array_merge($data['debug']['phpErrors'], elFinder::$phpErrors);
 }
 $out = json_encode($data);
 }
 while (ob_get_level() && ob_end_clean()) {
 }
 header('Content-Length: ' . strlen($out));
 echo $out;
 flush();
 }
 }
