I'm having a real disconnect on how to do this--partly due to my inexperience with working with the file system. I'm trying to create a script that will navigate the folders a files below it. The file currently works by listing the contents of the directory it's in (aka "."). I'm stumped on how to make it list contents of the folders below and the best way to do it. How would my script need reworking to fit this goal?
[code]
// sets ordering variables
$a = $_GET['a'];
// are you allowed to delete?
if($_SESSION['delete'] == "ON") {
$do_del = true;
}
else {
$do_del = false;
}
// scandir to opendir coversion from stackoverflow.com/questions/6823489/
$files_dir = ".";
$dir_handle = opendir($files_dir);
while ($dir_temp = readdir($dir_handle)) {
$arr_dir[] = $dir_temp;
}
closedir($dir_handle);
// function created by "acecream" on php.net; modified to include reverse sort
function sortArray($array, $key, $reverse = false)
{
if(isset($array)) {
foreach ($array as $i => $k)
{ $sort_values[$i] = $array[$i][$key]; }
if ($reverse == true)
{ arsort ($sort_values); }
else
{ asort ($sort_values); }
reset ($sort_values);
while (list ($arr_key, $arr_val) = each ($sort_values))
{ $sorted_arr[] = $array[$arr_key]; }
return $sorted_arr;
}
}
foreach($arr_dir as $file)
{
if(!preg_match("/(_vti)|(_borders)|(_private)|(hidden)|(~_)|(\.php)/", $file) && ($file != ".") && ($file !=".."))
{
$full = "$files_dir/$file";
$name = strval($file);
$size = sprintf("%u", filesize($full));
$kind = pathinfo($file, PATHINFO_EXTENSION); // strval(end(explode(".", $file)));
$mtime = filemtime($full); // modify date
$ctime = filectime($full); // creation date
$arr_files[] = array($name, $size, $kind, $mtime, $ctime);
}
}
$arr_count = count($arr_files);
switch ($a) {
case 1 : $arr_files = sortArray($arr_files, 0); break;
case 2 : $arr_files = sortArray($arr_files, 0, true); break;
case 3 : $arr_files = sortArray($arr_files, 1); break;
case 4 : $arr_files = sortArray($arr_files, 1, true); break;
case 5 : $arr_files = sortArray($arr_files, 2); break;
case 6 : $arr_files = sortArray($arr_files, 2, true); break;
case 7 : $arr_files = sortArray($arr_files, 3); break;
case 8 : $arr_files = sortArray($arr_files, 3, true); break;
default: $arr_files = sortArray($arr_files, 3, true); break;
}
unset($a);
function myFileSize($value) {
// convert raw byte site to friendlier forms
if($value > 1000) { $sizestr = round(($value/1024), 1) . " KB"; }
else { $sizestr = "$value B"; }
if($value > 1000000) { $sizestr = round(($value/1048576), 1) . " MB"; }
if($value > 1000000000) { $sizestr = round(($value/1073741824), 1) . " GB"; }
return $sizestr;
}
function myDate($value) {
$date = date("j M y G:i", $value);
return $date;
}
if($arr_count > 0)
{
if($do_del == true) {
print "<form method=\"post\" action=\"./?d=delete\">\n";
}
print "<table>\n";
print " <tr>\n";
print " <td>File Name</td>\n";
print " <td>Size</td>\n";
print " <td>Type</td>\n";
print " <td>Modified</td>\n";
print " <td>Created</td>\n";
if($do_del == true) {
print " <td>Delete?</td>\n";
}
print " </tr>\n";
print " <tr style=\"vertical-align: middle; background-color: #fff; border: 1px solid #000;\">\n";
print " <td>\n";
print " <img src=\"./~_arr-asc.gif\" border=\"0\">\n";
print " <img src=\"./~_arr-dsc.gif\" border=\"0\">\n";
print " </td>\n";
print " <td>\n";
print " <img src=\"./~_arr-asc.gif\" border=\"0\">\n";
print " <img src=\"./~_arr-dsc.gif\" border=\"0\">\n";
print " </td>\n";
print " <td>\n";
print " <img src=\"./~_arr-asc.gif\" border=\"0\">\n";
print " <img src=\"./~_arr-dsc.gif\" border=\"0\">\n";
print " </td>\n";
print " <td>\n";
print " <img src=\"./~_arr-asc.gif\" border=\"0\">\n";
print " <img src=\"./~_arr-dsc.gif\" border=\"0\">\n";
print " </td>\n";
print " <td> </td>\n";
if($do_del == true) {
print " <td> </td>\n";
}
print " </tr>\n";
for ($beat = 0; $beat < $arr_count; $beat++)
{
$name = $arr_files[$beat][0];
$size = $arr_files[$beat][1];
$ext = strtolower($arr_files[$beat][2]);
$mdate = $arr_files[$beat][3];
$cdate = $arr_files[$beat][4];
$size = myFileSize($size);
$mdate = myDate($mdate);
$cdate = myDate($cdate);
// pick the image for file type based on file extension
if(is_dir($name)) {
$pic = "~_folder.png";
}
else {
$pic = "~_file.png";
}
$url = "$name"; // create hard link
print " <tr>\n";
print " <td style=\"width: 300px;\"><img src=\"./$pic\"> $url</td>\n";
print " <td style=\"width: 75px;\">$size</td>\n";
print " <td style=\"width: 50px;\">$ext</td>\n";
print " <td style=\"width: 150px;\">$mdate</td>\n";
print " <td style=\"width: 150px;\">$cdate</td>\n";
if($do_del == true) {
print " <td><input type=\"checkbox\" name=\"list[$files_dir/$name]\" value=\"ON\"></td>\n";
}
print " </tr>\n";
}
print "</table>\n";
if($do_del == true) {
print " <p><input name=\"Submit1\" type=\"submit\" value=\"submit\">\n";
print " <input name=\"Reset1\" type=\"reset\" value=\"reset\"></p>\n";
print "</form>\n";
}
}
else
{
print "There are no files available for download.";
}
[/code]
Make your script a function that takes in the path.
Then in the while statement inside if(is_dir($file)) call your function and pass it $file.
For example,
function myFileSize($value) {...}
function myDate($value) {...}
function list_contents($path)
{
$dir_name = $path;
.
.
.
$dir = opendir($path);
.
.
.
while ($file = readdir($dir)) {
// do some stuff
if (is_dir($file)) {
list_contents($file);
}
}
}
Depending on what you want to do you will need to modify the output of the list_contents() function to work with the recursion. You could generate some tree structure using an array and then print the tree out later like:
// return an array representing tree structure
function list_contents($path, &$tree)
{
// ...
while ($file = readdir($dir)) {
$tree[$path][] = $file;
if (is_dir($file)) {
list_contents($file, $tree[$path]);
}
}
return $tree;
}
function print_tree($tree)
{
// code to display array using tree structure
}
$path = '.';
$dir_name = $path;
$tree_array = array();
$tree = list_contents($path, $tree_array)
print_tree($tree);
Or you could add a variable to count the number of levels in the method is
function list_contents($path, $level = 0)
{
//...
// indent output text by $level number of tabs
while($file = readdir($dir) {
if (is_dir($file)) {
list_contents($file, $level++)
}
}
}
list_contents($path);
Output would look something like
> Root
> Folder1 in root
> Folder2 in root
> Folder1 in Folder2
> Folder2 in Folder2
> Folder3 in root
> Folder1 in Folder3
> Folder1 in Folder1/Folder3
> File1 in Folder1
> File1 in root
> File2 in root
As a suggestion, I would take any functions related to getting file information or manipulating files and put them in their own file file_functions.php and then include that at the top of your script.
Related
I wrote a plugin for my site that is Ripley plugin
But when you copy the text to a user, it will be displayed as a code in the history
like this
{"action":"reply","umsg":"hi","uname":"admin","mymsg":"helo"}
The code I put in the history file is like this:
$jmsg = str_replace(array('<b>', '</b>', '<i>', '</i>'), '', $row['7']);
if (isJson($jmsg)) {
$jd = json_decode($jmsg, true);
if (isset($jd['action'])) {
$replymsg = $jd['umsg'];
$replyme = $jd['uname'];
$mymsg = $jd['mymsg'];
if ($jd['action'] == 'reply') {
if ($color == 'D5D5D7') {
$color = 'EEEEFF';
} else {
$color = 'D5D5D7';
}
echo "<msg><![CDATA[<tr id=\"msg-{$row['id']}\" bgcolor=\"#{$color}\"><td width=\"50\" align=\"center\">{$row['id']}{$delmsg}</td><td width=\"180\" align=\"center\">{$row['username']}</td><td width=\"80\" align=\"center\">" . jdate::start('Y/m/d H:i:s', $row['date']) . "</td><td align=\"center\" style=\"direction : rtl;word-break: break-all;max-width: 100px;font-family:{$row['fontname']};font-size:{$row['fontsize']}px;\"><div class=\"pmbox\"><div class=\"mess_back\"><div id=\"repbox\"><div id=\"khat\"><div id=\"name\">{$replyme}</div><div id=\"text\">{$replymsg}</div></div><div id=\"means\">{$mymsg}</div></div></div></div></td><td width=\"80\" align=\"center\">{$room}</td></tr>]]></msg>";
}
if ($jd['action'] == 'delete') {
continue;
}
if ($jd['action'] == 'reply') {
continue;
}
}
}
if ($color == 'D5D5D7') {
$color = 'EEEEFF';
} else {
$color = 'D5D5D7';
}
echo "<msg><![CDATA[<tr id=\"msg-{$row['id']}\" bgcolor=\"#{$color}\"><td width=\"50\" align=\"center\">{$row['id']}{$delmsg}</td><td width=\"180\" align=\"center\">{$row['username']}</td><td width=\"80\" align=\"center\">" . jdate::start('Y/m/d H:i:s', $row['date']) . "</td><td align=\"center\" style=\"direction : rtl;word-break: break-all;max-width: 100px;font-family:{$row['fontname']};font-size:{$row['fontsize']}px;\">{$row['text']}</td><td width=\"80\" align=\"center\">{$room}</td></tr>]]></msg>";
}
I have a html table which i fill in php in a complex logic.
There are 4 foreach loops to fill the data.
Now this works fine but through the loops i get some whitespace in my element.
The browser can display it fine, but as soon as I want to export this to a pdf, it will have some problems.
Anyone knows how to dismiss these whitespaces. Take a look at the image for more clarification:
Here's the code my variables which i echo out dont have any whitespaces. The problem also occur if give out echo "test";:
<div id="autoload-content">
<table class="tg" >
<thead>
<tr>
<th></th>
<th>Montag</th>
<th>Dienstag</th>
<th>Mittwoch</th>
<th>Donnerstag</th>
<th>Freitag</th>
</tr>
</thead>
<tbody>
<?php
$arrNoDoubleEntries = array();
$totalFactorMo = 0;
$stackIrregular = array();
//displays all the different presencetypes
foreach ($types as &$value) {
?>
<tr>
<td><?php echo ($value->Name);?></td>
<td>
<?php //all Monday Childs
if ($value->Name == "Total"){
echo ($totalFactorMo);
}else{
$childrenMonday = (Children::LoadPresence(1, $groupId));
foreach ($childrenMonday as &$child) {
foreach ($irregularPresence as &$irrugPrese){
if (($child->id == $irrugPrese->child_id) && ($monday >= $irrugPrese->datefrom) && ($monday <= $irrugPrese->dateto)){
if ($irrugPrese->away == 1 && ($value->id == $child->presencetype)){
echo("<s>".$child->fullName . " " . $child->factor."</s>");
echo "<br />";
array_push($stackIrregular, $child->id);
}
else{
if (($value->id == $irrugPrese->presencetype_id) AND (!(in_array($child->fullName + $irrugPrese->presencetype_id, $arrNoDoubleEntries)))){
echo("<u>".$child->fullName . " " . $child->factor."</u>");
echo "<br />";
array_push($arrNoDoubleEntries, $child->fullName + $irrugPrese->presencetype_id);
$totalFactorMo = $totalFactorMo + $child->factor;
}
}
}
}
if (!(in_array($child->id, $stackIrregular))) {
//prints the children which dont have some irregular Presences
if (!($child->presencetype == 1) && ($value->id == $child->presencetype)){
echo ($child->fullName . " " . $child->factor);
echo "<br />";
$totalFactorMo = $totalFactorMo + $child->factor;
}
}
}
}
?>
</td>
</tr>
</tbody>
</table>
</div>
in your case try to concatenate html and then show it like
<?php //all Monday Childs
$html = '';
if ($value->Name == "Total"){
$html .= ($totalFactorMo);
}else{
$childrenMonday = (Children::LoadPresence(1, $groupId));
foreach ($childrenMonday as &$child) {
foreach ($irregularPresence as &$irrugPrese){
if (($child->id == $irrugPrese->child_id) && ($monday >= $irrugPrese->datefrom) && ($monday <= $irrugPrese->dateto)){
if ($irrugPrese->away == 1 && ($value->id == $child->presencetype)){
$html .=("<s>".$child->fullName . " " . $child->factor."</s>");
$html .= "<br />";
array_push($stackIrregular, $child->id);
}
else{
if (($value->id == $irrugPrese->presencetype_id) AND (!(in_array($child->fullName + $irrugPrese->presencetype_id, $arrNoDoubleEntries)))){
$html .=("<u>".$child->fullName . " " . $child->factor."</u>");
$html .= "<br />";
array_push($arrNoDoubleEntries, $child->fullName + $irrugPrese->presencetype_id);
$totalFactorMo = $totalFactorMo + $child->factor;
}
}
}
}
if (!(in_array($child->id, $stackIrregular))) {
//prints the children which dont have some irregular Presences
if (!($child->presencetype == 1) && ($value->id == $child->presencetype)){
$html .= ($child->fullName . " " . $child->factor);
$html .= "<br />";
$totalFactorMo = $totalFactorMo + $child->factor;
}
}
}
}
echo $html;
?>
You can trim spaces from the variable before displaying in the table like
$string = preg_replace('/\s+/', '', $string);
or
$string = str_replace(' ', '', $string);
Just strip all the white space before printing the value.
EG:
function cleanSpaces($text)
{
$text = preg_replace('/(xC2xA0/| )','',$text); //remove
$text = preg_replace('/\s+/', '', $loop_variable_value); //remove whitespace
return $text;
}
I have the following script to display files inside a directory
<?PHP
# The current directory
$directory = dir("./");
# If you want to turn on Extension Filter, then uncomment this:
$allowed_ext = array(".deb", ".ext", ".ext", ".ext", ".ext", ".ext");
$do_link = TRUE;
$sort_what = 0; //0- by name; 1 - by size; 2 - by date
$sort_how = 0; //0 - ASCENDING; 1 - DESCENDING
# # #
function dir_list($dir){
$i=0;
$dl = array();
if ($hd = opendir($dir)) {
while ($sz = readdir($hd)) {
if (preg_match("/^\./",$sz)==0) $dl[] = $sz;$i.=1;
}
closedir($hd);
}
asort($dl);
return $dl;
}
if ($sort_how == 0) {
function compare0($x, $y) {
if ( $x[0] == $y[0] ) return 0;
else if ( $x[0] < $y[0] ) return -1;
else return 1;
}
function compare1($x, $y) {
if ( $x[1] == $y[1] ) return 0;
else if ( $x[1] < $y[1] ) return -1;
else return 1;
}
function compare2($x, $y) {
if ( $x[2] == $y[2] ) return 0;
else if ( $x[2] < $y[2] ) return -1;
else return 1;
}
}else{
function compare0($x, $y) {
if ( $x[0] == $y[0] ) return 0;
else if ( $x[0] < $y[0] ) return 1;
else return -1;
}
function compare1($x, $y) {
if ( $x[1] == $y[1] ) return 0;
else if ( $x[1] < $y[1] ) return 1;
else return -1;
}
function compare2($x, $y) {
if ( $x[2] == $y[2] ) return 0;
else if ( $x[2] < $y[2] ) return 1;
else return -1;
}
}
##################################################
# Getting The information
##################################################
$i = 0;
while($file=$directory->read()) {
$file = strtolower($file);
$ext = strrchr($file, '.');
if (isset($allowed_ext) && (!in_array($ext,$allowed_ext)))
{
// dump
}
else {
$temp_info = stat($file);
$new_array[$i][0] = $file;
$new_array[$i][1] = $temp_info[7];
$new_array[$i][2] = $temp_info[9];
$new_array[$i][3] = date("F d, Y", $new_array[$i][2]);
$i = $i + 1;
}
}
$directory->close();
##################################################
# Sorting the information
#################################################
switch ($sort_what) {
case 0:
usort($new_array, "compare0");
break;
case 1:
usort($new_array, "compare1");
break;
case 2:
usort($new_array, "compare2");
break;
}
###############################################################
# Displaying the information
###############################################################
$i2 = count($new_array);
$i = 0;
echo "<table class='CSSTableGenerator'>
<tr>
<td width=290>File name (Download)</td>
<td align=center width=70>Downloads</td>
<td align=center width=70>Depiction</td>
<td align=center width=50>Size</td>
<td align=center width=85>Modified</td>
</tr>";
for ($i=0;$i<$i2;$i++) {
if (!$do_link) {
$line = "<tr><td>" . $new_array[$i][0];
$line .= '</td><td>Depiction</td>';
$line .= "<td>" . number_format(($new_array[$i][1]/1024)) . " KB</td>";
$line .= "<td>" . $new_array[$i][3] . "</td></tr>";
}else{
$line = '<tr><td align=left ><A class="ex1" HREF="' .
$new_array[$i][0] . '">' .
$new_array[$i][0] .
"</A></td>";
$line .= '<td> </td>';
$line .= '<td>Depiction</td>';
$line .= "<td>" . number_format(($new_array[$i][1]/1024)) . " KB</td>";
$line .= "<td>" . $new_array[$i][3] . "</td></tr>";
}
echo $line;
}
echo "</table>";
?>
The output looks like that:
I am trying to fill the downloads column by getting the download counts of each file from mysql table
So i am facing 2 issues here:
How to get the stats using the array of the files $new_array[$i][0]
How can i then add this mysql query output inside $line .= '<td> </td>';
I have tried getting the stats from the table using this:
include("../config.php");
$query = "SELECT stats FROM download WHERE filename='$new_array[$i][0]'";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
$line .= '<td>' . $row['stats'] . '</td>';
}
but it didn't work, i think the issue is with the array $new_array[$i][0] because i tried writing a filename filename='com.name.app3_2.2-1_iphoneos-arm.deb' and i got the stats of this file
In your "getting the information part", you must initialise your arrays thusly:
##################################################
# Getting The information
##################################################
$i = 0;
$new_array = array();
while($file=$directory->read()) {
$file = strtolower($file);
$ext = strrchr($file, '.');
if (isset($allowed_ext) && (!in_array($ext,$allowed_ext)))
{
// dump
}
else {
$new_array[$i] = array();
$temp_info = stat($file);
$new_array[$i][0] = $file;
$new_array[$i][1] = $temp_info[7];
$new_array[$i][2] = $temp_info[9];
$new_array[$i][3] = date("F d, Y", $new_array[$i][2]);
$i = $i + 1;
}
}
$directory->close();
##################################################
In addition, I have noted that your line:
$query = "SELECT stats FROM download WHERE filename='$new_array[$i][0]'";
Would cause $query to be equal to:
SELECT stats FROM download WHERE filename='Array[0]'
When $i is 0.
What you should do is use the mysqli library thusly:
$mysqli = new mysqli("example.com", "user", "password", "database");
$query = "SELECT stats FROM download WHERE filename=?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param('s', $new_array[$i][0]);
$stmt->execute();
$stmt->bind_result($stats);//stats turns into a reference by default.
while($stmt->fetch()) { //$stats now contains the stats
$line .= '<td>'. htmlentities($stats).'</td>';
}
To deal with the problem of missing cells you just described, you might try:
$mysqli = new mysqli("example.com", "user", "password", "database");
$query = "SELECT stats FROM download WHERE filename=?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param('s', $new_array[$i][0]);
$stmt->execute();
$stmt->bind_result($stats);//stats turns into a reference by default.
$fetched = false;
while($stmt->fetch()) { //$stats now contains the stats
$line .= '<td>'. htmlentities($stats).'</td>';
$fetched = true;
}
if(!$fetched) {
$line .= '<td></td>'
}
I have used to the Rackspace API to upload files to the RackSpace cloud. But this method seems to be a little on the slow side. Is there a better or faster way to upload a file to the cloud(curl, http adapters, etc)?
I am currently uploading with PHP and using the provided API.
Here is my solution how to make it fast:
I'm uploading only missing files using simple PHP script below. Thanks to it I do it in just one click and in just a few seconds.
PHP source code:
function UploadMissingFilesToRackFileCDN($file_paths_to_upload, $b_force_upload = false)
{
include_once("cloudfiles.php");
// Connect to Rackspace
$username = cloudfile_username; // username
echo "Connecting to CDN..." . date("H:i:s") . "<br>"; ob_flush();
$key = cloudfile_api_key; // api key
$auth = new CF_Authentication($username, $key);
$auth->authenticate();
$conn = new CF_Connection($auth);
echo " Connected!" . date("H:i:s") . "<br>"; ob_flush();
// Get the container we want to use
$container_name = 'vladonai';//'test_container';
echo "Obtaining container $container_name..." . date("H:i:s") . "<br>"; ob_flush();
$container = $conn->get_container($container_name);
echo " The container is obtained." . date("H:i:s") . "<br>"; ob_flush();
if (!$b_force_upload)
{
echo "Receiving container objects list..." . date("H:i:s") . "<br>"; ob_flush();
$existing_object_names = $container->list_objects();
$existing_files_count = count($existing_object_names);
echo " Objects list obtained: $existing_files_count." . date("H:i:s") . "<br>"; ob_flush();
$existing_object_names_text .= "\r\n";
foreach ($existing_object_names as $obj_name)
{
$existing_object_names_text .= $obj_name . "\r\n";
}
}
// upload files to Rackspace
$uploaded_file_n = 0;
$skipped_file_n = 0;
$errors_count = 0;
foreach ($file_paths_to_upload as $localfile_path => $file_info)
{
$filename = basename($localfile_path);
if (!file_exists($localfile_path))
{
echo "<font color=red>Error! File $localfile_path doesn't exists!</font>" . date("H:i:s") . "<br>"; ob_flush();
$errors_count ++;
} else
if (is_dir($localfile_path))
{
//simply skip it
} else
if (strpos($existing_object_names_text, "\r\n" . $filename . "\r\n") !== false)
{
//file is already uploaded to CDN (at least file name is present there). Would be good to have date/size checked, but CDN api has no such feature
//echo "<font color=gray>Skipped file $localfile_path - it already exists!</font><br>"; ob_flush();
$skipped_file_n ++;
} else
{
echo "<font color=green>Uploading file $localfile_path (file #$uploaded_file_n)..." . date("H:i:s") . "</font><br>"; ob_flush();
try
{
$object = $container->create_object($filename);
$object->load_from_filename($localfile_path);
$uploaded_file_n ++;
}
catch (Exception $e)
{
echo "<font color=red>Error! Caught exception: ", $e->getMessage(), " on uploading file <strong>$localfile_path</strong>!</font>" . date("H:i:s") . "<br>"; ob_flush();
$errors_count ++;
}
}
// if ($uploaded_file_n >= 10)
// break;
}
echo "Done! $uploaded_file_n files uploaded. Disconnecting :)" . date("H:i:s") . "<br>"; ob_flush();
echo "Skipped files: $skipped_file_n<br>"; ob_flush();
if ($errors_count > 0)
echo "<font color=red>Erorrs: $errors_count</font><br>"; ob_flush();
}
function UploadChangedImagesToRackFileCDN($b_force_upload = false)
{
$exclude = array
(
'.',
'..',
'*.html',
'*.htm',
'*.php',
'*.csv',
'*.log',
'*.txt',
'*.cfg',
//'*sub/forum/files/*',
);
$files_array_images = get_dirlist("/var/www/html/vladonai.com/images/", '*', $exclude, false);
$files_array = array_merge(get_dirlist("/var/www/html/vladonai.com/js/", '*', $exclude, false), $files_array_images);
UploadMissingFilesToRackFileCDN($files_array, $b_force_upload);
}
function get_dirlist($path, $match = '*', $exclude = array( '.', '..' ), $b_short_path = true)
{
$result = array();
if (($handle = opendir($path)))
{
while (false !== ($fname = readdir($handle)))
{
$skip = false;
if (!empty($exclude))
{
if (!is_array($exclude))
{
$skip = fnmatch($exclude, $fname) || fnmatch($exclude, $path . $fname);
} else
{
foreach ($exclude as $ex)
{
if (fnmatch($ex, $fname) || fnmatch($ex, $path . $fname))
$skip = true;
}
}
}
if (!$skip && (empty($match) || fnmatch($match, $fname)))
{
$file_full_path_and_name = $path . $fname;
//echo "$file_full_path_and_name<br>";
$b_dir = is_dir($file_full_path_and_name);
$b_link = is_link($file_full_path_and_name);
$file_size = ($b_dir || $b_link) ? 0 : filesize($file_full_path_and_name);
$file_mod_time = ($b_dir || $b_link) ? 0 : filemtime($file_full_path_and_name);
$new_result_element = array();
if ($b_short_path)
$file_name = str_replace("/var/www/html/vladonai.com/", "", $file_full_path_and_name);//'[' . str_replace("/var/www/html/vladonai.com/", "", $file_full_path_and_name) . ']';
else
$file_name = $file_full_path_and_name;
$result[$file_name] = array();
$result[$file_name]['size'] = $file_size;
$result[$file_name]['modtime'] = $file_mod_time;
if ($b_dir && !$b_link)
{
//recursively enumerate files in sub-directories
$result = array_merge(get_dirlist($file_full_path_and_name . "/", $match, $exclude, $b_short_path), $result);
}
}
}
closedir($handle);
}
return $result;
}
I have a list of directory name and need to get the first letter from each name and just display it once before the start of that lettered group ie;
what I have:
1
2
3
4
5
Aberdeen
Arundel
Aberyswith
Bath
Bristol
Brighton
Cardiff
coventry
what I would like:
#
1
2
3
4
5
A
Aberdeen
Arundel
Aberyswith
B
Bath
Bristol
Brighton
C
Cardiff
coventry
function htmlDirList($subdirs) {
global $z_self, $z_img_play, $z_img_lofi, $z_img_more, $z_admin,
$z_img_down, $z_img_new, $zc;
$now = time();
$diff = $zc['new_time']*60*60*24;
$num = 0;
$dir_list_len = $zc['dir_list_len'];
if ($zc['low']) { $dir_list_len -= 2; }
$html = "";
$checkbox = ($z_admin || ($zc['playlists'] && $zc['session_pls']));
/**/
$row = 0;
$items = sizeof($subdirs);
$cat_cols = "2";
$rows_in_col = ceil($items/$cat_cols);
if ($rows_in_col < $cat_cols) { $cat_cols = ceil($items/$rows_in_col); }
$col_width = round(100 / $cat_cols);
$html = "<table width='600'><tr>";
$i = 0;
/**/
foreach ($subdirs as $subdir => $opts) {
if ($row == 0) {
$class = ($cat_cols != ++$i) ? ' class="z_artistcols"' : '';
$html .= "<td $class valign='top' nowrap='nowrap' width='$col_width%'>";
}
/*$currentleter = substr($opts, 0 , 1);
if($lastletter != $currentleter){
echo $currentleter;
$lastletter = $currentleter;
}*/
if($alphabet != substr($opts,0,1)) {
echo strtoupper(substr($opts,0,1)); // add your html formatting too.
$alphabet = substr($opts,0,1);
}
$dir_len = $dir_list_len;
$dir = false;
$image = $opts['image'];
$new_beg = $new_end = "";
if (substr($subdir, -1) == "/") {
$dir = true;
$subdir = substr($subdir, 0, -1);
}
$path_raw = getURLencodedPath($subdir);
$href = "<a href='$path_raw";
if (!$dir) {
if ($zc['download'] && $zc['cmp_sel']) { $html .= "$href/.lp&l=8&m=9&c=0'>$z_img_down</a> "; }
if ($zc['play']) { $html .= "$href&l=8&m=0'>$z_img_play</a> "; }
if ($zc['low'] && ($zc['resample'] || $opts['lofi'])) { $html .= "$href&l=8&m=0&lf=true'>$z_img_lofi</a> "; }
if ($checkbox) { $html .= "<input type='checkbox' name='mp3s[]' value='$path_raw/.lp'/> "; }
$num++;
if ($zc['new_highlight'] && isset($opts['mtime']) && ($now - $opts['mtime'] < $diff)) {
$dir_len -= 5;
if ($z_img_new) {
$new_end = $z_img_new;
} else {
$new_beg = $zc['new_beg'];
$new_end = $zc['new_end'];
}
}
}
$title = formatTitle(basename($subdir));
if (strlen($title) > $dir_len) {
$ht = " title=\"$title.\"";
$title = substr($title,0,$dir_len).$opts['mtime']."...";
} else {
$ht = "";
}
if ($zc['dir_list_year']) {
$di = getDirInfo($subdir);
if (!empty($di['year'])) $title .= " (".$di['year'].")";
}
$html .= "$href'$ht>$new_beg$title$new_end</a><br />";
$row = ++$row % $rows_in_col;
if ($row == 0) { $html .= "</td>"; }
}
if ($row != 0) $html .= "</td>";
$html .= "</tr></table>";
$arr['num'] = $num;
$arr['list'] = $html;
return $arr;
}
I need help to get work.
The following will display the list of directories, beginning each group with a first letter as beginning of the group (see codepad for proof):
(this assumes $dirs is array containing the names)
$cur_let = null;
foreach ($dirs as $dir) {
if ($cur_let !== strtoupper(substr($dir,0,1))){
$cur_let = strtoupper(substr($dir,0,1));
echo $cur_let."\n";
}
echo $dir . "\n";
}
You just need to add some formatting on your own, suited to your needs.
Edit:
Version grouping under # sign entries that begin with a number, can look like that:
$cur_let = null;
foreach ($dirs as $dir) {
$first_let = (is_numeric(strtoupper(substr($dir,0,1))) ? '#' : strtoupper(substr($dir,0,1)));
if ($cur_let !== $first_let){
$cur_let = $first_let;
echo $cur_let."\n";
}
echo $dir . "\n";
}
Please see codepad as a proof.
Is this what you are looking for?
<?php
$places = array(
'Aberdeen',
'Arundel',
'Aberyswith',
'Bath',
'Bristol',
'Brighton',
'Cardiff',
'coventry'
);
$first_letter = $places[0][0];
foreach($places as $p)
{
if(strtolower($p[0])!=$first_letter)
{
echo "<b>" . strtoupper($p[0]) . "</b><br/>";
$first_letter = strtolower($p[0]);
}
echo $p . "<br/>";
}
?>
Prints:
A
Aberdeen
Arundel
Aberyswith
B
Bath
Bristol
Brighton
C
Cardiff
coventry
My approach would be to generate a second array that associates the first letter to the array of names that begin with that letter.
$dirs; // assumed this contains your array of names
$groupedDirs = array();
foreach ($dirs as $dir) {
$firstLetter = strtoupper($dir[0]);
$groupedDirs[$firstLetter][] = $dir;
}
Then, you can iterate on $groupedDirs to print out the list.
<?php foreach ($groupedDirs as $group => $dirs): ?>
<?php echo $group; ?>
<?php foreach ($dirs as $dir): ?>
<?php echo $dir; ?>
<?php endforeach; ?>
<?php endforeach; ?>
This allows for a clean separation between two separate tasks: figuring out what the groups are and, secondly, displaying the grouped list. By keeping these tasks separate, not only is the code for each one clearer, but you can reuse either part for different circumstances.
Use something like this, change it to output the HTML the way you want thouugh:
sort($subdirs);
$count = count($subdirs);
$lastLetter = '';
foreach($subdirs as $subdir => $opts){
if(substr($subdir,0,1) !== $lastLetter){
$lastLetter = substr($subdir,0,1);
echo '<br /><div style="font-weight: bold;">'.strtoupper($lastLetter).'</div>';
}
echo '<div>'.$subdir.'</div>';
}
EDIT
Just realized $subdir is associative, made the change above: