
 

 <?php 

/*Copyright © 2024-2025 Laurynas Andriuska, needee.net

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0


Unless agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//wget https://needee.net/ui-builder.php && sudo mkdir /etc/needee/ && sudo chown www-data:www-data /etc/needee/ && sudo chmod 750 /etc/needee/ && sudo chown www-data:www-data ui-builder.php
$config_dir = '/etc/needee/';
$targetDir='published/';

 $config_file = $config_dir . 'login-data.conf';
 $first_launch="";
 $version=1.1;
 // ini_set('display_errors', 1);
  //ini_set('display_startup_errors', 1);

  //ini_set('session.gc_maxlifetime','2592000');
 session_start();

if(isset($_SESSION['logged_in'])&&$_SESSION['logged_in']){
 if(isset($_POST['write']) ){
  header('Content-Type: application/json; charset=utf-8');

  try {if(!user_verify())throw new Exception("File browser unavailable for public users!", 0);

      $path = $_POST["dir"];
      if(isset($_POST['filepath'])&&$_POST['filepath'])$path.=$_POST['filepath'];
    
    str_replace('//', '/', $path);
      $results = writeToFile($path,$_POST['content']);
      
      // Format the response
      if($results){
      $response = [
          'status' => 'success',
          'timestamp' => date('Y-m-d H:i:s'),
        "path"=>$path,
          'ok' => 'true'
      ];
      
      echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);exit;}
      else throw new Exception("Error:", 1);
  } catch (Exception $e) {
      http_response_code(500);
      echo json_encode([
          'status' => 'error',
          'timestamp' => date('Y-m-d H:i:s'),
          'isfile' => 'true',
          'message' => $e->getMessage()
      ], JSON_PRETTY_PRINT);
  }
exit;}
 if(isset($_GET['load'])){
  header('Content-Type: application/json; charset=utf-8');
 
  try { if(!user_verify())throw new Exception("File browser unavailable for public users!", 0);
  
      // Get directory path from query parameter or use current directory
      $dirPath = isset($_GET['path']) ? $_GET['path'] : '.';
      
      $results = loadHtmlFile($dirPath);
      
      // Format the response
      $response = [
          'status' => 'success',
          'timestamp' => date('Y-m-d H:i:s'),
          'directory' => realpath($dirPath),
          'isfile' => 'true',
          'url'=>getCurrentPageUrl(),
          'current_path'=> __DIR__,
          'content' => $results
      ];
      
      echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
      
  } catch (Exception $e) {
      http_response_code(500);
      echo json_encode([
          'status' => 'error',
          'timestamp' => date('Y-m-d H:i:s'),
          'isfile' => 'true',
          'message' => $e->getMessage()
      ], JSON_PRETTY_PRINT);
  }
exit;}
if(isset($_GET['create'])&&isset( $_SESSION['logged_in'])&&$_SESSION['logged_in']){
  header('Content-Type: application/json; charset=utf-8');
 
  try { if(!user_verify())throw new Exception("File browser unavailable for public users!", 0);

    
    $path = isset($_GET['path']) ? $_GET['path'] : '.';



    $info = pathinfo($path);
    $isFile = isset($info['extension']);
    
    // Get directory path
    $dirPath = $isFile ? $info['dirname'] : $path;
    
    // Create parent directories if they don't exist
    if (!is_dir($dirPath)) {
        if (!mkdir($dirPath, 0777, true)) {
            throw new Exception("Failed to create directory: " . $dirPath." ".error_get_last()['message']);
        }
    }
    
    // If path is a file, create it
    if ($isFile) {
        if (file_put_contents($path, "") === false) {
            throw new Exception("Failed to create file: ".error_get_last()['message']);
        }
    }
    
   

      $response = [
          'status' => 'success',
          'timestamp' => date('Y-m-d H:i:s'),
          'directory' => $directory,
         'filepath'=>$_GET['path'],
         
          'current_path'=> __DIR__,
          'content' => "true"
        ];
      
      echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
      
  } catch (Exception $e) {
      http_response_code(500);
      echo json_encode([
          'status' => 'error',
          'timestamp' => date('Y-m-d H:i:s'),
          'directory' => $directory,
          'message' => $e->getMessage()
      ], JSON_PRETTY_PRINT);
  }
exit;}
if(isset($_GET['rename'])){
  header('Content-Type: application/json; charset=utf-8');
 
  try { if(!user_verify())throw new Exception("File browser unavailable for public users!", 0);
  
      // Get directory path from query parameter or use current directory


      $dirPath = isset($_GET['path']) ? $_GET['path'] : '.';
      if(!isset($_GET['path']))throw new Exception("Error Processing Request:");
    $paths=  explode(",",htmlspecialchars( $_GET['path']));
      $old_path =$paths[0];
      $new_path=$paths[1];
     $results = rename_dir_file($old_path,$new_path);
       if(!$results)throw new Exception("Error Processing Request: Check Permissions!", 1);
       
      // Format the response
      $response = [
          'status' => 'success',
          'timestamp' => date('Y-m-d H:i:s'),
        'ignore'=>true
      ];
      
      echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
      
  } catch (Exception $e) {
      http_response_code(500);
      echo json_encode([
          'status' => 'error',
          'timestamp' => date('Y-m-d H:i:s'),
          'oldpath' => $old_path,
          'newpath'=> $new_path,
          'message' => $e->getMessage()
      ], JSON_PRETTY_PRINT);
  }
exit;}
if(isset($_GET['delete'])){
  header('Content-Type: application/json; charset=utf-8');
 
  try { if(!user_verify())throw new Exception("File browser unavailable for public users!", 0);
  
      // Get directory path from query parameter or use current directory
      if(!isset($_GET['path']))throw new Exception("Error Processing Request:");
    
      $dirPath=explode(",",htmlspecialchars( $_GET['path']));
      $results = deleteFilesDirs($dirPath);
      
      // Format the response
      $response = [
          'status' => 'success',
          'timestamp' => date('Y-m-d H:i:s'),
          'directory' => $dirPath,
         
        
         
          'content' => $results
      ];
      
      echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
      
  } catch (Exception $e) {
      http_response_code(500);
      echo json_encode([
          'status' => 'error',
          'timestamp' => date('Y-m-d H:i:s'),
          'isfile' => 'true',
          'message' => $e->getMessage()
      ], JSON_PRETTY_PRINT);
  }
exit;}
 if(isset($_GET['list'])){
  header('Content-Type: application/json; charset=utf-8');
 
  try {
    if(!user_verify())throw new Exception("File browser unavailable for public access users!", 0);
    
      // Get directory path from query parameter or use current directory
      $dirPath = isset($_GET['path']) ? $_GET['path'] : '.';
      
      $results = scanDirectory($dirPath);
      
      // Format the response
      $response = [
          'status' => 'success',
          'timestamp' => date('Y-m-d H:i:s'),
          'directory' => realpath($dirPath),
          'version' => $version,
          'data' => $results
      ];
      
      echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
      
  } catch (Exception $e) {
      http_response_code(500);
      echo json_encode([
          'status' => 'error',
          'timestamp' => date('Y-m-d H:i:s'),
          'message' => $e->getMessage()
      ], JSON_PRETTY_PRINT);
  }
exit;}

}


 if(!isset($_POST['publishing_aswrrgybtrg5sfw53s'])){ 
  // Create config directory if it doesn't exist
 if (!file_exists($config_dir)) {
 
  if (mkdir($config_dir, 0755,true)) {
    echo "Directory created successfully: $config_dir\n<br>";
} else {
    echo "<h4 style='color:red;'>Failed to create directory $config_dir: " . error_get_last()['message'] . "\n</h4><br>";
}
 }

 // Function to read login data
 
 
 // Check if user is logged in
 if (isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true) {
     echo "<div style='    position: absolute; z-index: 100; left: 0px; bottom: 0%; padding: 9px; box-shadow: 0 0 5px; background-color: whitesmoke;'>". htmlspecialchars($_SESSION['user']) . "";
     echo "<br><a href='?logout=1'>Logout</a></div>";
     
 }
 
 // Handle logout
 if (isset($_GET['logout'])) {
     session_destroy();
     header('Location: ' . $_SERVER['PHP_SELF']);
     exit;
 }
 
 // Check if first launch
 $first_launch = !file_exists($config_file);
 echo "<script>var nd_version=$version;</script>";
 if (isset($_GET['skip'])&&$first_launch) {
  $_SESSION['logged_in'] = true;
             $_SESSION['user'] = "Public Access";
             echo "<div style='    position: absolute; z-index: 100; left: 0px; bottom: 0%; padding: 9px; box-shadow: 0 0 5px; background-color: whitesmoke;'>". htmlspecialchars($_SESSION['user']) . "";
             echo "<br><a href='?logout=1'>Logout</a></div>";
  //header('Location: ' . $_SERVER['PHP_SELF']);
 // exit;
}
 // Handle form submissions
 if ($_SERVER['REQUEST_METHOD'] === 'POST'&&isset($_POST['password'])) {
 if(isset($_POST['t_dir']) ) $targetDir=$_POST['t_dir'];
 $user =$_POST['user'];
   //  $user = filter_var($_POST['user'], FILTER_SANITIZE_EMAIL);
     $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
     
     if ($first_launch) {
         // Registration
         if (saveLoginData($user, $password,$targetDir)) {
             $_SESSION['logged_in'] = true;
             $_SESSION['user'] = $user;
             $_SESSION['password']=$password;
             $_SESSION['target_dir']=$targetDir;
             header('Location: ' . $_SERVER['PHP_SELF']);
             exit;
         } else {
             $error = "Registration failed. Email already exists.";
         }
     } else {
         // Login
         $users = readLoginData();
         if (isset($users[$user]) && password_verify($_POST['password'], $users[$user]['password'])) {
             $_SESSION['logged_in'] = true;
             $_SESSION['user'] = $user;
             $_SESSION['password']=$password;

             $_SESSION['target_dir']=$users[$user]['targetDir'];
             $_SESSION['id']=$users[$user]['id'];
             header('Location: ' . $_SERVER['PHP_SELF']);
             exit;
         } else {sleep(4);
             $error = "Invalid email or password.";
         }
     }
 }}

 ?>
  <?php if ((!isset( $_SESSION['logged_in'])||$first_launch)&&!isset($_GET['skip'])&&!isset($_POST['publishing_aswrrgybtrg5sfw53s'])): ?>
 <!DOCTYPE html>
 <html>
 <head>
     <title><?php echo $first_launch ? 'Register' : 'Login'; ?></title>
     <style>
         body {
             font-family: Arial, sans-serif;
             max-width: 400px;
             margin: 50px auto;
             padding: 20px;
         }
         .error {
             color: red;
             margin-bottom: 10px;
         }
         input {
             width: 100%;
             padding: 8px;
             margin: 5px 0 15px;
             box-sizing: border-box;
         }
         button {
             background-color: #4CAF50;
             color: white;
             padding: 10px 15px;
             border: none;
             cursor: pointer;
             width: 100%;
         }
         button:hover {
             background-color: #45a049;
         }
     </style>
 </head>
 <body>
     <h2><?php echo $first_launch ? 'Login Wall Setup' : 'Login'; ?></h2>
     
     <?php if (isset($error)): ?>
         <div class="error"><?php echo htmlspecialchars($error); ?></div>
     <?php endif; ?>
     
    
      
   

     <form method="post">

  
     <label for="email">Email / Username:</label>
     <input type="text" id="email" name="user" required>
         
         <label for="password">Password:</label>
         <input type="password" id="password" name="password" required>
         <?php if ($first_launch): ?>
      
      <label for="t_dir">Publish Target Directory:</label>
      <input type="text" id="t_dir" name="t_dir" value="<?php echo htmlspecialchars($targetDir); ?>" >
  <?php endif; ?>
         
         <button type="submit"><?php echo $first_launch ? 'Register' : 'Login'; ?></button>
         
         <?php if ($first_launch): ?>
            <br>  <br>
            <a href="" onclick="event.preventDefault(); generateRandomPassword()">Generate Password</a>
             <p><small>Setup is optional. You can skip this step. File explorer won't be available for public access users. </small></p>
             <p><strong>install command line:</strong><br><small>sudo mkdir /etc/needee/ && sudo chown www-data:www-data /etc/needee/ && sudo chmod 750 /etc/needee/ && sudo chown www-data:www-data ui-builder.php</small> </p>
             <a href="?skip=1">Skip setup </a>
         <?php endif; ?>
     </form>
     <script>
        function generateRandomPassword() {
           document.getElementById('email').value="user1";
            const length = 16; // Length of the generated password
            const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+';
            let randomPassword = '';

            for (let i = 0; i < length; i++) {
                const randomIndex = Math.floor(Math.random() * characters.length);
                randomPassword += characters.charAt(randomIndex);
            }

            document.getElementById('password').value = randomPassword;
        }
    </script>
 </body>
 </html>


 <?php if(!isset( $_SESSION['logged_in'])|| ($_SESSION['logged_in']!==true)||$first_launch) exit ;?>

  <?php endif; ?>









<?php

 $sess_id="";
if ($_SERVER['REQUEST_METHOD'] === 'POST'&&isset($_POST['publishing_aswrrgybtrg5sfw53s'])&&isset( $_SESSION['logged_in'])) {  
    if(!user_verify()){echo "7_1 Publishing not available for public access users!"; exit;}
  if($_POST['session_id_needee']==$_SESSION['session_id_needee']){
  
    if(isset($_SESSION['target_dir']))$targetDir=$_SESSION['target_dir'];
    if (isset($_FILES['userfile'])) {
     $target_file=$_FILES['userfile']['name'];
     $fileName =basename($_FILES['userfile']['name']);
     $path="";
    if(isset( $_POST['pathname']))  $path=str_replace('../','/',$_POST['pathname'])."/";
   // log_data("path: ".$_POST['pathname']."\r\n");
  $targetPath = $targetDir.$path;log_data("targetpath: ".$targetPath."\r\n");
     if (!is_dir($targetPath))   mkdir($targetPath, 0755, true);
      // Create the directory  
        $FileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    

        if (move_uploaded_file($_FILES['userfile']['tmp_name'], $targetPath.$fileName)) {

          if($FileType != "zip") {echo "1_1"; exit;}
   
       
      
system("unzip -o ".$targetPath.$fileName." -d ".$targetPath); 

if (file_exists($targetPath.$fileName)) 
  // Remove the file
  if (unlink($targetPath.$fileName))

// Get the host
//$host = $_SERVER['HTTP_HOST'];

// Get the request URI and remove the file name
$requestUri = dirname($_SERVER['REQUEST_URI']);

// Construct the URL without the file name
$latestFile = '';
$latestTimestamp = 0;

// Open the directory
if ($handle = opendir($targetPath)) {
    // Loop through each entry in the directory
    while (false !== ($entry = readdir($handle))) {
        // Check if the entry is a file
        if (is_file($targetPath.$entry)) {
            // Get the file's timestamp
            $fileTimestamp = filemtime($targetPath .$entry);

            // Compare timestamps to find the latest file
            if ($fileTimestamp > $latestTimestamp) {
                $latestFile =htmlspecialchars($entry);
                $latestTimestamp = $fileTimestamp;
            }
        }
    }

    // Close the directory handle
    closedir($handle);
  }
    // Output the most recently created file name
   // echo "The most recently created file in the directory is: " . htmlspecialchars($latestFile);
// Output the result

$host="https://".$_SERVER['SERVER_NAME'].$requestUri."/".$targetPath.$latestFile;
         echo"<a target='_blank' href='$host'>$host</a>";
          echo "1_1";   
          exit (); }
        
            $file = 'file.zip';

// get the absolute path to $file
$path = pathinfo(realpath($file), "/var/www/html/needee.net/php/");


        } else {
            echo "Error uploading file.";
            exit;
        }
    } else {
        echo "No file selected.";
    
  }
}else{
 $sess_id= $_SESSION['session_id_needee']=str_rand();
}
function bin2Ancii($input)
{for($i=0; $i<strlen($input); $i+=8) {
  $output .= chr(intval(substr($input, $i, 8), 2));
}
return $output;
  # code...
}
function str_rand(int $length = 64){ // 64 = 32
  $length = ($length < 4) ? 4 : $length;
  return bin2hex(random_bytes(($length-($length%2))/2));
}
function log_data($dat){
  $file=file_put_contents('../../../log_data.txt',$dat." ",FILE_APPEND);
  }//socketse
?> 


<!--email_off-->
<!DOCTYPE html>
<html style="overflow: hidden;" lang="en">

<head><script async src="https://www.googletagmanager.com/gtag/js?id=G-1MN8VH3FG2"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-1MN8VH3FG2');
</script>
	<meta charset="UTF-8">
	<meta name="description"
		content="Drag & drop HTML editor for building responsive web pages and user interfaces/online documents. Doesn't require coding.">
	<meta name="keywords"
		content="HTML editor, website builder, drag & drop HTML designer, drag & drop HTML editor, nocode HTML editor">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>NEEDEE HTML editor - website builder/</title>
    <script defer src="https://needee.net/distzip/jszip.min.js"></script>


         <iframe  width="100%" style="position: absolute; height: 100%; border: none;" src="https://needee.net/ui-builder-hosted.html" frameborder="0"></iframe>

  
  
  <style >:root { --helper-color: #007bff; }
.card_needee { min-width: 250px; font-family: system-ui; background-color: rgba(255, 255, 255, 0.6); width: fit-content; max-width: 600px; margin: 20px; box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 8px 0px; border-radius: 6px; padding: 30px !important; }
.alert_needee { z-index: 99; min-width: "min-content"; border-style: double; border-color: var(--helper-color); border-radius: 20px; border-width: 10px; background-color: rgba(0, 0, 0, 0.78); color: rgb(255, 255, 255); box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 17px 8px; }
.alert_needee button { float: right; border-style: solid; border-color: rgb(255, 255, 255); border-width: 1px; background-color: var(--helper-color); min-width: 100px; width: fit-content; font-weight: 700; color: white; }
.alert_needee button:hover { background-color: green; border-color: green; }
.card_button_needee { border-radius: 5px; display: block; padding: 5px; width: fit-content; border-width: 3px; border-style: solid; box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 6px 0px; margin-left: auto; margin-right: 0px; border-color: rgb(255, 255, 255); }
.colors_needee { color: rgb(119, 119, 119); background-color: rgb(238, 238, 238); }
.colors_needee:hover { background-color: rgb(214, 214, 214); }
.animate_needee { transition: opacity 350ms ease-in-out, transform 150ms ease-in-out; }
a { color: var(--helper-color); }
.center_a_needee { transform: translate(-50%, -50%); top: 50% !important; left: 50% !important; }
.hide_alert { transform: translate(-50%, -1600px); }
</style>
</head>
<body>


<dialog id="alert-needee" style="position: fixed; z-index: 99; width: fit-content;max-width:min-content; display: block; border-radius: 23px;" open class="animate_needee alert_needee card_needee center_a_needee hide_alert">   

<h3 style="font-size: 35px;">Info</h3>   
<p style="font-size: 21px; width: fit-content; min-width: 200px; margin-bottom: 44px;" id="p_2088">
<br></p>
<button onclick="needeealertbox.classList.add('hide_alert'); needeealertbox.children[0].innerHTML = '';needeealertbox.children[1].innerHTML ='';"   class="card_button_needee" style="background-color: transparent; color: rgb(255, 255, 255);" id="button_6035">Cancel</button>
<button onclick="needeealertbox.classList.add('hide_alert'); needeealertbox.children[0].innerHTML = '';needeealertbox.children[1].innerHTML ='';"  class="card_button_needee" style="margin: 0px 13px 0px 20px; background-color: var(--helper-color); color: white;" id="button_1685">Ok</button> 
</dialog>
  
  <script>
var dirHandle; siteName = "";
var needeealertbox = document.getElementById("alert-needee");
function addToFormData(formData, prefix = '', value) {
    if (value instanceof Object && !(value instanceof Array)) {
        // Handle nested objects
        for (let [key, v] of Object.entries(value)) {
            addToFormData(formData, `${prefix}${key}.`, v);
        }
    } else if (Array.isArray(value)) {
        // Handle arrays
        value.forEach((v, i) => {
            addToFormData(formData, `${prefix}[${i}].`, v);
        });
    } else {
        // Add the value to FormData
        formData.append(prefix.slice(0, -1), value); // Remove trailing '.'
    }
}
window.addEventListener('message', (event) => {
    if (event.origin === 'https://needee.net') {
        var saveInterv = true;
        let sess_id = "<?php echo $sess_id; ?>";
        const receivedData = event.data;
        // Assuming the received data contains a filename and content
        const { action, filepath, path, _name, content, key } = receivedData;


       






        if (action) {
            if (action == "write") {

                async function respond() {
                    console.log('Message from child:', receivedData);
                    // Create a new FormData object
                    const formData = new FormData();

                    // Add all properties of the JSON object to the FormData
                    addToFormData(formData, '', receivedData);

                    //   const response =await  fetch(`${window.location.href.split("?")[0]}?write=1&path=${encodeURIComponent(filepath)}`);
                    const response = await fetch(window.location.href.split("?")[0], {
                        method: 'POST',

                        body: formData //JSON.stringify(receivedData) //JSON.stringify({"write":1,"path":filepath,})
                    });
                    //event.source.postMessage({resp: response}, "https://needee.net/ui-builder-hosted.html")
                    document.querySelector("iframe").contentWindow.postMessage(await response.json(), '*');
                    //event.source.postMessage({resp: response}, event.origin);


                }
                respond();
            } else { respond(path?path:filepath); async function respond(path) {

            const response = await fetch(`${window.location.href.split("?")[0]}?${action}=1${path == "." ? "" : "&path=" + encodeURIComponent(path)}`);

            //event.source.postMessage({resp: response}, "https://needee.net/ui-builder-hosted.html")
            try {
                document.querySelector("iframe").contentWindow.postMessage(await response.json(), '*');
            } catch (error) {
                document.querySelector("iframe").contentWindow.postMessage({
                    'status': 'error',

                    'message': 'something went wrong!'
                }, '*');
            }

            console.log("response:" + response);

        } }


      return;   }






        if (key < 5)
            window.showDirectoryPicker().catch(e => { clearInterval(saveInterv); })
                .then(dirHandle => verifyPermission(dirHandle).then(

                    (dirHandle) => {
                        const zipFile = content;
                        siteName = _name;



                        if (dirHandle) if (key == 4) JSZip.loadAsync(zipFile).then((zip) =>
                            Object.keys(zip.files).forEach(function (filename) {
                                zip.files[filename].async('blob').then(function (data) {
                                    if (!zip.files[filename].dir) writeBlobToFile(dirHandle, data, siteName + "/" + filename)


                                }




                                )
                            })).then(() => alert("Folder Saved")); else if (key == 3) { writeBlobToFile(dirHandle, content, _name + ".zip"); alert("File '" + _name + ".zip' saved"); }

                        else if (key == 1 || key == 2) {
                            writeBlobToFile(dirHandle, content, _name);

                            alert("File '" + _name + "' saved");
                        }

                    }));








        if (key == "copy") try {
            navigator.clipboard.writeText(content);
            //   console.log('Text copied to clipboard successfully');
            return;
        } catch (error) {
            //      console.error('Failed to copy text:', error.message);
        }
        if (key > 5) {
            var blobData = content;

            var file = new File([blobData], _name + ".zip", {

            });
        }
        if (key == 5) {
            var blobData = new Blob([content], { type: "text/html" });

            var file = new File([blobData], _name, {
                type: "text/html"

            });
        }
        // Upload file
        if (file && file.size > 0) {

            var formData = new FormData();
            formData.append("pathname", _name);
            formData.append("userfile", file);
            formData.append("publishing_aswrrgybtrg5sfw53s", 1);
            formData.append('session_id_needee', sess_id);
            var xhttp = new XMLHttpRequest();

            // Set POST method and ajax file path
            xhttp.open("POST", window.location.href, true);

            // call on request changes state
            xhttp.onreadystatechange = function () {
                if (this.readyState == 4) {
                    if (this.status == 200) {
                        var response = this.responseText;
                        if (response.indexOf("1_1") > -1) {
                            needeeAlert("Uploaded successfully." + response.replace("1_1", ""));
                        } else {
                            if (response.indexOf("7_1") > -1) { needeeAlert("No files uploaded. Publishing not available for public access users!"); return; }
                            alert("No files uploaded. " + (response.toString().indexOf("ZipArchive") > -1 ? "Error:No ZipArchive!!! Install php ZipArchiver with 'sudo apt install php-zip'" : response)); return;
                        }
                    } else {

                        alert("Error:" + this.status + (this.status.toString().indexOf("413") > -1 ? "(File too large. Increase your server's max upload & post size limit!)" : ""));
                    }
                }

            };

            // Send request with data
            xhttp.send(formData);

        }

    }
}

);

async function verifyPermission(fileHandle) {

    const options = {};

    options.mode = 'readwrite';
    if (fileHandle == dirHandle) return dirHandle;
    else
        if ((await fileHandle.queryPermission(options)) === 'granted') {
            dirHandle = await fileHandle;
            return dirHandle;
        } else
            // Request permission. If the user grants permission, return true.
            if ((await fileHandle.requestPermission(options)) === 'granted') {
                dirHandle = await fileHandle;
                //await neeUtils.saveSettings();
                return dirHandle;
            }
    // The user didn't grant permission, so return false.
    return false;
}
async function writeBlobToFile(dirH, blob, path) {
    // Create a FileSystemWritableFileStream to write to.

    var arr = path.split("/");
    var ind = 0;
    createDirStructure(arr[ind], dirH);


    async function createDirStructure(dir, dirH) {
        if (dir.indexOf(".") < 0)
            dirH.getDirectoryHandle(dir, {
                create: true
            }).then(dirH => { ind++; createDirStructure(arr[ind], dirH) });
        else dirH.getFileHandle(dir, { create: true }).then(
            dirH => dirH.createWritable()).then(writable => writable.write(blob).then(() => writable.close()));
    }

}
function needeeAlert(text, cap, time = 1000000) {
    if (cap) needeealertbox.children[0].textContent = cap;
    else needeealertbox.children[0].innerHTML = "Info";
    needeealertbox.children[1].innerHTML = text;
    needeealertbox.classList.remove("hide_alert");
    setTimeout(() => { needeealertbox.classList.add("hide_alert"); }, time);

}
function getUrlPath(url = window.location.href) {

    const urlParts = url.split('/');

    if (urlParts.length > 3) urlParts.pop();


    return urlParts.join('/');
}


</script>
     </body>

</html>



<?php









function scanDirectory($path = '.') {
    // Normalize and validate the path
    $path = rtrim($path, '/\\');
    
    if (!is_dir($path)) {
        throw new Exception("Invalid directory path: $path, or invalid permissions!");
    }
    
    $result = [
        'folders' => [],
        'html_files' => []
    ];
    
    try {
        $items = new DirectoryIterator($path);
        
        foreach ($items as $item) {
            // Skip . and .. directories
            if ($item->isDot()) {
                continue;
            }
            
            $fullPath = $item->getRealPath();
            $relativePath = substr($fullPath, strlen(realpath($path)) + 1);
            
            if ($item->isDir()) {
                $result['folders'][] = [
                    'name' => $item->getFilename(),
                    'path' => $relativePath,
                    'full_path' => $fullPath,
                    'modified' => date('Y-m-d H:i:s', $item->getMTime()),
                    'permissions' => substr(sprintf('%o', fileperms($fullPath)), -4)
                ];
            } 
            elseif ($item->isFile() 
            && (strtolower($item->getExtension()) === 'html' ||   strtolower($item->getExtension()) === 'htm' ||   strtolower($item->getExtension()) === 'css')
                     ) {
                $result['html_files'][] = [
                    'name' => $item->getFilename(),
                    'path' => $relativePath,
                    'full_path' => $fullPath,
                    'size' => $item->getSize(),
                    'modified' => date('Y-m-d H:i:s', $item->getMTime()),
                    'permissions' => substr(sprintf('%o', fileperms($fullPath)), -4)
                ];
            }
        }
        
        // Sort results alphabetically by name
        usort($result['folders'], function($a, $b) {
            return strcasecmp($a['name'], $b['name']);
        });
        
        usort($result['html_files'], function($a, $b) {
            return strcasecmp($a['name'], $b['name']);
        });
        
        return $result;
        
    } catch (Exception $e) {
        throw new Exception("Error scanning directory: " . $e->getMessage());
    }
}
function loadHtmlFile($filePath) {
  // Extract the extension from the file path
  $fileExtension = pathinfo($filePath, PATHINFO_EXTENSION);

  // Check if the file has a .html or .htm extension
  if (strtolower($fileExtension) === 'html' || strtolower($fileExtension) === 'htm'||strtolower($fileExtension) === 'css') {
      // Check if the file exists
      if (file_exists($filePath)) {
          // Read the contents of the file
          $htmlContent = file_get_contents($filePath);
          
          // Return the HTML content
          return $htmlContent;
      } else {
          // File does not exist, you can handle this case as needed
          return throw new Exception("File not found or invalid permissions.", 0); ;
      }
  } else {
      // The file has an incorrect extension
      return throw new Exception("Invalid file format. Please provide a .html or .htm file. You gave: $filePath",0);
  }
}

// Usage

function getCurrentPageUrl() {
  $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http";
  $host = $_SERVER['HTTP_HOST'];
  $uri = $_SERVER['REQUEST_URI'];

  // Remove the file name from the URI
  $urlWithoutFile = preg_replace('@/[^/]*$@', '', $uri);

  // Combine the protocol, host, and URL without the file
  $fullUrl = "$protocol://$host$urlWithoutFile";

  return $fullUrl;
}

function writeToFile($filePath, $content) {
  // Check if the directory exists and create it if not
  $directory = dirname($filePath);
  if (!is_dir($directory)) {
      mkdir($directory, 0777, true); // Create directory recursively with permissions 0777
  }

  // Write content to the file
  if (file_put_contents($filePath, $content) !== false) {
      return "Operation successfull.";
  } else {
      throw new Exception(error_get_last()['message'], 1);
  }
}
function create_dir_file($filePath) {
  // Check if the directory exists and create it if not

 
}function createFileOrFolder($path) {
  $info = pathinfo($path);
  
  if (isset($info['extension'])) {
      // It's a file, so create it using touch()
      return touch($path) ? true : false;
  } else {
      // It's a folder, so create it using mkdir()
      return mkdir($path, 0755, true) ? true : false;
  }
}

function deleteFilesDirs($paths) {
  $result = [];
  foreach ($paths as $path) {
      if (file_exists($path)) {
          if (is_dir($path)) {
              // Recursive directory deletion
              $result[$path] = deleteDirectory($path);
          } else {
              // File deletion
              $result[$path] = unlink($path) ? 'success' : 'error';
          }
      } else {
          $result[$path] = 'error'; // Path does not exist
      }
  }
  return $result;
}

function deleteDirectory($dirPath) {
  if (!is_dir($dirPath)) return false;
  
  $objects = glob($dirPath.'/*');
  foreach ($objects as $object) {
      if (is_dir($object)) {
          deleteDirectory($object); // Recursive call for subdirectories
      } else {
          unlink($object);
      }
  }
  rmdir($dirPath);
  return true;
}
function isHtmlFile($path) {
    // Get the file extension of the path
    $ext = pathinfo($path, PATHINFO_EXTENSION);
    
    // Check if the file extension is either 'html' or 'htm'
    return strtolower($ext) === 'html' || strtolower($ext) === 'htm';
}

 function readLoginData() {
    global $config_file;
    $users = [];
    if (file_exists($config_file)) {
        $lines = file($config_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        foreach ($lines as $line) {
            list($id, $user, $password, $targetDir) = explode(':', $line);
            $users[$user] = ['id' => $id, 'password' => $password,'target_dir'=>$targetDir];
        }
    }
    return $users;
}
function rename_dir_file($old_path, $new_name) {
    // Check if path exists
    if (!file_exists($old_path)) {
        return false;
    }

    // Get directory path and construct new full path
    $dir_path = dirname($old_path);
    $new_path = $dir_path . DIRECTORY_SEPARATOR . $new_name;

    // Check if target already exists
    if (file_exists($new_path)) {
        return false;
    }

    // Validate new name (no special chars except - and _)
    if (!preg_match('/^[a-zA-Z0-9-_\.]+$/', $new_name)) {
        return false;
    }

    // Perform rename operation
    try {
        return rename($old_path, $new_path);
    } catch (Exception $e) {
        return false;
    }
}
// Function to save login data
function saveLoginData($user, $password,$targetDir
) { 
    global $config_file;
    $users = readLoginData();
    if (!isset($users[$user])) {
      $_SESSION['id']= $id = count($users) + 1;
        $data = "$id:$user:$password:$targetDir\n";
        file_put_contents($config_file, $data, FILE_APPEND);
     
        return true;
    }
    return false;
}
function user_verify(){
     $users = readLoginData();
  //return true;  
  
     if (isset($users[$_SESSION['user']]) &&isset($_SESSION['password'])&&($_SESSION['id']==$users[$_SESSION['user']]['id'])  /* ($_SESSION['password']==$users[$_SESSION['user']]['password']) */ )return true;
     else  return false;
 }
?>