PHP Directory Tree - Deleting Folders - php

I have found a script that lists all directories and files in them, and allows for the deletion of files.
I have two problems:
1) How do I add the function to delete a folder (With all the contents in it)
2) How do I make the script not to allow a user to browse up a directory? (For e.g. a user's folder is ./files/$userid/. I want it so that a user won't be able to go to or make any changes to ./files/ or a folder other then ./files/$userid/
$script = basename(__FILE__); // the name of this script
$path = !empty($_REQUEST['path']) ? $_REQUEST['path'] : dirname('./files/' . (string)$userid . '/'); // the path the script should access
$unlink = $_REQUEST['unlink'];
if(!empty($unlink)){
$unlink = realpath("$path/$unlink");
if(is_writable($unlink) && !unlink($unlink)){
echo "<div class=\"error\">Unable to delete file: $unlink</div>";
}
}
echo "<p>Browsing Location: {$path}</p>";
$directories = array();
$files = array();
// Check we are focused on a dir
if (is_dir($path)){
chdir($path); // Focus on the dir
if ($handle = opendir('.')){
while (($item = readdir($handle)) !== false) {
// Loop through current directory and divide files and directorys
if(is_dir($item)){
array_push($directories, realpath($item));
}
else{
array_push($files, ($item));
}
}
closedir($handle); // Close the directory handle
}
else {
echo "<p class=\"error\">Directory handle could not be obtained.</p>";
}
}
else{
echo "<p class=\"error\">Path is not a directory</p>";
}
// List the directories as browsable navigation
echo "<h2>Navigation</h2>";
echo "<ul>";
foreach($directories as $directory){
$delete = is_writable($file) ? "<a class=\"unlink\" href=\"{$script}?path={$path}&unlink={$directory}\">delete</a>" : '';
echo ($directory != $path) ? "<li>{$directory}</li>" : "";
}
echo "</ul>";
echo "<h2>Files</h2>";
echo "<ul>";
foreach($files as $file){
// Comment the next line out if you wish see hidden files while browsing
if(preg_match("/^\./", $file) || $file == $script){continue;} // This line will hide all invisible files.
$delete = is_writable($file) ? "<a class=\"unlink\" href=\"{$script}?path={$path}&unlink={$file}\">delete</a>" : '';
echo '<li>' . $file . " $delete</li>";
}
echo "</ul>";

1) Try use this function to delete folder recursively (see manual, User contributed notes section http://php.net/manual/en/function.rmdir.php):
function delTree($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
2) Better develop some filemanager to allow users browse certain folders. Or see some ready solutions: http://www.jquery4u.com/plugins/10-jquery-file-manager-plugins/

Related

PHP Is there a way to display my list from the foreach separately?

I want to display the links separately. One list would include all the .html links and the other all the .jpg links.
right now it displays this and I understand why it is doing it, but when i do another foreach outside or even right before the echo, its like nothing is passing into it.
.jpg
.html
.jpg
.html
I need it to display like this
HTML-Backup HTML
.jpg .html
.jpg .html
php Code
$array = array();
$html= "";
$htmlBackup= "";
if(file_exists("uploads/" . $_POST["prefix"] .'/'))
{
$dir = 'uploads/' . $_POST["prefix"] . '/';
$files = preg_grep('~\.(jpeg|jpg|png)$~', scandir($dir));
$prefixDir = scandir($dir);
foreach($prefixDir as $dir_files)
{
$secondDir = $dir . $dir_files;
//$finalDir=scandir($secondDir);
if((is_dir($secondDir)))
{
$finalDir=preg_grep('~\.(html|jpg)$~', scandir($secondDir));
$i = 0;
foreach($finalDir as $lastDir)
{
if(strpos($lastDir, "HTML5.jpg") !== false)
{
echo''.$lastDir.' </br>';
//variable to store list of dir
$html=$lastDir;
} else if(strpos($lastDir, "HTML5.html") !== false )
{
echo''.$lastDir.' </br>';
//variable to store the list of dir
$htmlBackup=$lastDir;
}
}
}
}
}
Don't put <br> at the end of each echo. Do it after the inner loop so all links from the same directory will be on the same line.
foreach($prefixDir as $dir_files)
{
$secondDir = $dir . $dir_files;
//$finalDir=scandir($secondDir);
if((is_dir($secondDir)))
{
$finalDir=preg_grep('~\.(html|jpg)$~', scandir($secondDir));
$i = 0;
foreach($finalDir as $lastDir)
{
if(strpos($lastDir, "HTML5.jpg") !== false)
{
echo''.$lastDir.'';
//variable to store list of dir
$html=$lastDir;
} else if(strpos($lastDir, "HTML5.html") !== false )
{
echo''.$lastDir.'';
//variable to store the list of dir
$htmlBackup=$lastDir;
}
}
echo "<br>";
}
}
I found a solution by including arrays.
foreach($prefixDir as $dir_files)
{
$secondDir = $dir . $dir_files;
//$finalDir=scandir($secondDir);
if((is_dir($secondDir)))
{
$finalDir=preg_grep('~\.(html|jpg)$~', scandir($secondDir));
$i = 0;
foreach($finalDir as $lastDir)
{
if(strpos($lastDir, "HTML5.html") !== false || strpos($lastDir, "H5.html") !== false)
{
//variable to store the list of dir
array_push($html_array, $lastDir);
array_push($html_dir,$secondDir.'/'.$lastDir);
}
else if(strpos($lastDir, "HTML5.jpg") !== false || strpos($lastDir, "H5.jpg")!== false )
{
//variable to store list of dir
array_push($html_backup_array, $lastDir);
array_push($html_backup_dir,$secondDir.'/'.$lastDir);
}
}
}
}
and then display them under in another foreach as I want
if(!empty($html_array))
{
echo "<p>";
echo ("<p><span class='heading'>HTML5 Units</span></p>");
foreach (array_combine($html_dir, $html_array) as $html_dirr => $html_arrays)
{
echo (''.$html_arrays.'');
echo "<br>";
}
echo "</p>";
}

Loop through directory and get the files using PHP and wrap the each folder files in ul li element

I have following PHP function which return all the folder with files in html li element from a given path.
function folderTree ($directory_path) {
if(!file_exists($directory_path)) {
die("The file $directory_path is not exists");
}
if(!is_dir($directory_path)) {
die("This directory $directory_path can't open");
}
$directory = opendir($directory_path);
$filenames = [];
while ($filename = readdir($directory)) {
if($filename !== '.' && $filename !== '..') {
if(is_dir($directory_path.'/'.$filename)) {
$filename .= '/';
}
$filenames[] = $filename;
}
}
echo "<ul>";
foreach ($filenames as $filename) {
echo "<li><a href='{$directory_path}/{$filename}'>";
echo $filename;
if(substr($filename, -1) == '/' ) {
folderTree($directory_path.'/'.substr($filename, 0, -1)).'/lv2/';
}
echo "</a></li>";
}
echo "</ul>";
}
now It's working fine and the output this below:
img-01
img01.jpg
img02.jpg
img03.jpg
img-02
img01.jpg
img02.jpg
img03.jpg
img-03
img01.jpg
img02.jpg
img03.jpg
This img-01, 02 and 03 is a folder and there are .jpg files exist.
Now, You can see the code above that it's wrapping all the files of all folders in a single ul element, right.
But I want it should wrap each folder by folder not all at once.
Now the code output is something like that:
<ul><li>jpg...</li><li>jpg...</li><li>jpg...</li><li>jpg...</li> só on..</ul>
But I need:
<ul><li>jpg...</li><li>jpg...</li><li>jpg...</li></ul>
<ul><li>jpg...</li><li>jpg...</li><li>jpg...</li></ul>
<ul><li>jpg...</li><li>jpg...</li><li>jpg...</li></ul>

Why am I not getting the directory hierarchy?

The following code is meant to display directories as well as sub directories within the directories and the files inside them. I used chmod function to gain access to directories.
This code runs but doesn't display the directory hierarchy, which means it is unable to list the sub directories and the files inside.
As I run the script, I get this warning :
Warning: chmod(): No such file or directory in E:\Installed_Apps\xampp\htdocs\dlist.php on line 5
-
#recursive function
function directory_f_lister($root) {
$dir_list = scandir($root);
for($var=0;$var<count($dir_list);$var++) {
$bool = chmod($root.$dir_list[$var], 0777);
if(is_readable($root.$dir_list[$var])) {
if(is_dir($root.$dir_list[$var])) {
if($dir_list[$var] === "." || $dir_list[$var] === "..") continue;
echo "<h3>Name of directory $dir_list[$var]</h3>";
echo "<br />";
$dh = opendir($root.$dir_list[$var]);
while(($name = readdir($dh)) !== false) {
if(is_dir($root.$dir_list[$var].$name)) {
if($dir_list[$var] === "." || $dir_list[$var] === "..") continue;
echo "Name of directory : <strong> $name </strong>";
echo "<br />";
directory_f_lister($root.$dir_list[$var].$name);
}else {
echo $name;
echo "<br/>";
}
}
}
} else { "<b>else statement <br /> </b>"; }
}
}
directory_f_lister(DIRECTORY_SEPARATOR);
What is the problem ? Why am I not getting the directory hierarchy ?
chmod(realpath(dirname(__FILE__)).'/'.$dir_list[$var], 0777);

How to retrieve files on a directory in list using PHP

How may i able to retrieve different file extensions in a certain directory. Let say i have a folder named "downloads/", where inside that folder are different types of files like PDFs, JPEGs, DOC files etc. So in my PHP code i wanted those files be retrieved and listed with there file names and file extensions. Example: Inside "downloads/" folder are different files
downloads/
- My Poem.doc
- My Photographs.jpg
- My Research.pdf
So i wanted to view those files where i can get there file names, file extensions, and file directories. So in view will be something like this
Title: My Poem
Type: Document
Link: [url here]
Title: My Photographs
Type: Image
Link: [url here]
Title: My Research
Type: PDF
Link: [url here]
Anyone knows how to do it in php? Thanks a lot!
It's pretty simple. To be honest i don't know why didn't you searched on a php.net. They got whole lots of examples for this. Check it in here: click
Example:
<?php
function process_dir($dir,$recursive = FALSE) {
if (is_dir($dir)) {
for ($list = array(),$handle = opendir($dir); (FALSE !== ($file = readdir($handle)));) {
if (($file != '.' && $file != '..') && (file_exists($path = $dir.'/'.$file))) {
if (is_dir($path) && ($recursive)) {
$list = array_merge($list, process_dir($path, TRUE));
} else {
$entry = array('filename' => $file, 'dirpath' => $dir);
//---------------------------------------------------------//
// - SECTION 1 - //
// Actions to be performed on ALL ITEMS //
//----------------- Begin Editable ------------------//
$entry['modtime'] = filemtime($path);
//----------------- End Editable ------------------//
do if (!is_dir($path)) {
//---------------------------------------------------------//
// - SECTION 2 - //
// Actions to be performed on FILES ONLY //
//----------------- Begin Editable ------------------//
$entry['size'] = filesize($path);
if (strstr(pathinfo($path,PATHINFO_BASENAME),'log')) {
if (!$entry['handle'] = fopen($path,r)) $entry['handle'] = "FAIL";
}
//----------------- End Editable ------------------//
break;
} else {
//---------------------------------------------------------//
// - SECTION 3 - //
// Actions to be performed on DIRECTORIES ONLY //
//----------------- Begin Editable ------------------//
//----------------- End Editable ------------------//
break;
} while (FALSE);
$list[] = $entry;
}
}
}
closedir($handle);
return $list;
} else return FALSE;
}
$result = process_dir('C:/webserver/Apache2/httpdocs/processdir',TRUE);
// Output each opened file and then close
foreach ($result as $file) {
if (is_resource($file['handle'])) {
echo "\n\nFILE (" . $file['dirpath'].'/'.$file['filename'] . "):\n\n" . fread($file['handle'], filesize($file['dirpath'].'/'.$file['filename']));
fclose($file['handle']);
}
}
?>
You could use glob & pathinfo:
<?php
foreach (glob(__DIR__.'/*') as $filename) {
print_r(pathinfo($filename));
}
?>
You will try this code :
$Name = array();
$ext = array();
$downloadlink = array();
$dir = 'downloads'
while ($file= readdir($dir))
{
if ($file!= "." && $file!= "..")
{
$temp = explode(".",$file);
if (count($temp) > 1)
{
$Name[count($Name)] = $temp[0];
swich($ext)
{
case "doc" :
{
$ext[count($ext)] = "Document";
break;
}
[...]
default :
{
$ext[count($ext)] = "Error";
break;
}
}
$downloadlink[count($downloadlink)] = "http://yourdomain.com/".$dir."/".$file;
}
}
}
closedir($dir);
for($aux = 0; $aux < count($Name); $aux++)
{
echo "Name = " . $Name[$aux]."<br />
Type = " . $ext[$aux]."<br/>
Link = " . $downloadlink[$aux]."<br/>
";
}

How to get innermost directory name

I am trying to output a class based on the name of innermost directory name, but can't get it right. Any help would be very much appreciated. It's a php_file_tree, please see section numbered #39 below:
function php_file_tree_dir($directory, $return_link, $extensions = array(), $first_call = TRUE) {
// Get and sort directories/files
if (function_exists("scandir")) {
$file = scandir($directory);
}
else {
$file = php4_scandir($directory);
}
natcasesort($file);
// Make directories first
$files = $dirs = array();
foreach ($file as $this_file) {
if (is_dir("$directory/$this_file")) {
$dirs[] = $this_file;
}
else $files[] = $this_file;
}
$file = array_merge($dirs, $files);
// Filter unwanted extensions
if (!empty($extensions)) {
foreach (array_keys($file) as $key) {
if (!is_dir("$directory/$file[$key]")) {
$ext = substr($file[$key], strrpos($file[$key], ".") + 1);
if (!in_array($ext, $extensions))unset($file[$key]);
}
}
}
// Use 2 instead of 0 to account for . and .. "directories"
if (count($file) > 2) {
$php_file_tree = "<ul";
if ($first_call) {
$php_file_tree .= " class=\"php-file-tree clearfix\"";
$first_call = FALSE;
}
// #39, Here needs to output a class based on innermost directory name
/*
else {
$php_file_tree .= " class=\"innertree ". htmlspecialchars(basename(rtrim($directory, '/'))) ." clearfix\"";
}
*/
$php_file_tree .= ">";
foreach ($file as $this_file) {
if ($this_file != "." && $this_file != "..") {
if (is_dir("$directory/$this_file")) {
// Directory
$php_file_tree .= "<li class=\"pft-directory\"><a class=\"folder \" href=\"#\">". htmlspecialchars($this_file) ."</a>";
$php_file_tree .= php_file_tree_dir("$directory/$this_file", $return_link, $extensions, FALSE);
$php_file_tree .= "</li>";
}
else {
//$ext = "ext-". substr($this_file, strrpos($this_file, ".") + 1); // need to compare speed with native
$ext = "ext-". pathinfo($this_file, PATHINFO_EXTENSION);
$link = str_replace("[link]", base_path() ."$directory/". urlencode($this_file), $return_link);
$php_file_tree .= "<li class=\"pft-file ". strtolower($ext) ."\"><a class=\"screenshot\" title=". htmlspecialchars($this_file) ." href=\"$link\">". htmlspecialchars($this_file) ."</a></li>";
}
}
}
$php_file_tree .= "</ul>";
}
return $php_file_tree;
}
The topmost directory will always have a class "php-file-tree", while the subsequent/ following directories underneath will have their classes based on their own folder names.
Geez, actually it was okay already. Seems the problem was cache or something as I placed it inside modal dialog with AJAX call. I have tried several possibilities before, including "$first_call = FALSE;" to no avail. But when I revisited the directory again, added "$first_call = FALSE;", and clear everything, it now output the folder name correctly.
Sorry to bother, anyone. Thanks

Categories