Click to See Complete Forum and Search --> : Modifying Preg_find


kudzugazette
08-03-2008, 06:17 PM
Okay, so trying to sort dirdisplay didn't work, so I decided to use preg_find instead. Everything is perfect except for the fact that the results display like this:

1) 2008-08-03 Resources/Students/Report all other problems
2) 2008-08-03 Resources/Students/PRS Clicker Instructions
3) 2008-08-03 Resources/Students/Copyright Violation Policy

When I want them to display like this:
1) 2008-08-03 Report all other problems
2) 2008-08-03 PRS Clicker Instructions
3) 2008-08-03 Copyright Violation Policy

Here is the preg_find code:
<?php
/*
* Find files in a directory matching a pattern
*
*
* Paul Gregg <pgregg@pgregg.com>
* 20 March 2004, Updated 20 April 2004
* Updated 18 April 2007 to add the ability to sort the result set
* Updated 9 June 2007 to prevent multiple calls to sort during recursion
* Version: 2.2
* This function is backwards capatible with any code written for a
* previous version of preg_find()
*
* Open Source Code: If you use this code on your site for public
* access (i.e. on the Internet) then you must attribute the author and
* source web site: http://www.pgregg.com/projects/php/preg_find/preg_find.phps
* Working examples: http://www.pgregg.com/projects/php/preg_find/
*
*/

define('PREG_FIND_RECURSIVE', 1);
define('PREG_FIND_DIRMATCH', 2);
define('PREG_FIND_FULLPATH', 4);
define('PREG_FIND_NEGATE', 8);
define('PREG_FIND_DIRONLY', 16);
define('PREG_FIND_RETURNASSOC', 32);
define('PREG_FIND_SORTDESC', 64);
define('PREG_FIND_SORTKEYS', 128);
define('PREG_FIND_SORTBASENAME', 256); # requires PREG_FIND_RETURNASSOC
define('PREG_FIND_SORTMODIFIED', 512); # requires PREG_FIND_RETURNASSOC
define('PREG_FIND_SORTFILESIZE', 1024); # requires PREG_FIND_RETURNASSOC
define('PREG_FIND_SORTDISKUSAGE', 2048); # requires PREG_FIND_RETURNASSOC

// PREG_FIND_RECURSIVE - go into subdirectorys looking for more files
// PREG_FIND_DIRMATCH - return directorys that match the pattern also
// PREG_FIND_DIRONLY - return only directorys that match the pattern (no files)
// PREG_FIND_FULLPATH - search for the pattern in the full path (dir+file)
// PREG_FIND_NEGATE - return files that don't match the pattern
// PREG_FIND_RETURNASSOC - Instead of just returning a plain array of matches,
// return an associative array with file stats
//
// You can also request to have the results sorted based on various criteria
// By default if any sorting is done, it will be sorted in ascending order.
// You can reverse this via use of:
// PREG_FIND_SORTDESC - Reverse order of sort
// PREG_FILE_SORTKEYS - Sort on the keyvalues or non-assoc array results
// The following sorts *require* PREG_FIND_RETURNASSOC to be used as they are
// sorting on values stored in the constructed associative array
// PREG_FIND_SORTBASENAME - Sort the results in alphabetical order on filename
// PREG_FIND_SORTMODIFIED - Sort the results in last modified timestamp order
// PREG_FIND_SORTFILESIZE - Sort the results based on filesize
// PREG_FILE_SORTDISKUSAGE - Sort based on the amount of disk space taken
// to use more than one simply seperate them with a | character



// Search for files matching $pattern in $start_dir.
// if args contains PREG_FIND_RECURSIVE then do a recursive search
// return value is an associative array, the key of which is the path/file
// and the value is the stat of the file.
Function preg_find($pattern, $start_dir='.', $args=NULL) {

static $depth = -1;
++$depth;

$files_matched = array();

$fh = opendir($start_dir);

while (($file = readdir($fh)) !== false) {
if (strcmp($file, '.')==0 || strcmp($file, '..')==0) continue;
$filepath = $start_dir . '/' . $file;
if (preg_match($pattern,
($args & PREG_FIND_FULLPATH) ? $filepath : $file)) {
$doadd = is_file($filepath)
|| (is_dir($filepath) && ($args & PREG_FIND_DIRMATCH))
|| (is_dir($filepath) && ($args & PREG_FIND_DIRONLY));
if ($args & PREG_FIND_DIRONLY && $doadd && !is_dir($filepath)) $doadd = false;
if ($args & PREG_FIND_NEGATE) $doadd = !$doadd;
if ($doadd) {
if ($args & PREG_FIND_RETURNASSOC) { // return more than just the filenames
$fileres = array();
if (function_exists('stat')) {
$fileres['stat'] = stat($filepath);
$fileres['du'] = $fileres['stat']['blocks'] * 512;
}
if (function_exists('fileowner')) $fileres['uid'] = fileowner($filepath);
if (function_exists('filegroup')) $fileres['gid'] = filegroup($filepath);
if (function_exists('filetype')) $fileres['filetype'] = filetype($filepath);
if (function_exists('mime_content_type')) $fileres['mimetype'] = mime_content_type($filepath);
if (function_exists('dirname')) $fileres['dirname'] = dirname($filepath);
if (function_exists('basename')) $fileres['basename'] = basename($filepath);
if (isset($fileres['uid']) && function_exists('posix_getpwuid')) $fileres['owner'] = posix_getpwuid ($fileres['uid']);
$files_matched[$filepath] = $fileres;
} else
array_push($files_matched, $filepath);
}
}
if ( is_dir($filepath) && ($args & PREG_FIND_RECURSIVE) ) {
$files_matched = array_merge($files_matched,
preg_find($pattern, $filepath, $args));
}
}

closedir($fh);

// Before returning check if we need to sort the results.
if (($depth==0) && ($args & (PREG_FIND_SORTKEYS|PREG_FIND_SORTBASENAME|PREG_FIND_SORTMODIFIED|PREG_FIND_SORTFILESIZE|PREG_FIND_S ORTDISKUSAGE)) ) {
$order = ($args & PREG_FIND_SORTDESC) ? 1 : -1;
$sortby = '';
if ($args & PREG_FIND_RETURNASSOC) {
if ($args & PREG_FIND_SORTMODIFIED) $sortby = "['stat']['mtime']";
if ($args & PREG_FIND_SORTBASENAME) $sortby = "['basename']";
if ($args & PREG_FIND_SORTFILESIZE) $sortby = "['stat']['size']";
if ($args & PREG_FIND_SORTDISKUSAGE) $sortby = "['du']";
}
$filesort = create_function('$a,$b', "\$a1=\$a$sortby;\$b1=\$b$sortby; if (\$a1==\$b1) return 0; else return (\$a1<\$b1) ? $order : 0- $order;");
uasort($files_matched, $filesort);
}
--$depth;
return $files_matched;

}

?>



And here is the code on the page:
<?php
include 'resources/inc/preg_find.php';
$students = preg_find('/./', 'Resources/Students',
PREG_FIND_RECURSIVE|PREG_FIND_RETURNASSOC|PREG_FIND_SORTMODIFIED|PREG_FIND_SORTDESC);
$facandstaff = preg_find('/./', 'Resources/FacandStaff',
PREG_FIND_RECURSIVE|PREG_FIND_RETURNASSOC|PREG_FIND_SORTMODIFIED|PREG_FIND_SORTDESC);
$i=1;?>

<div id="r_students">
<h2>Resources for students</h2>
<?php foreach($students as $file => $stats) {
printf('<br>%d) %s <a href="show.php?page=%s">%s</a>', $i,
date('Y-m-d', $stats['stat']['mtime']), $file, $file);
$i++;
if ($i > 10) break;
}?>
</div>
<div id="r_staff">
<h2>Resources for Faculty and Staff</h2>
<?php foreach($facandstaff as $file => $stats) {
printf('<br>%d) %s <a href="show.php?page=%s">{$file}</a>', $i,
date('Y-m-d', $stats['stat']['mtime']), $file, $file);
$i++;
if ($i > 10) break;
}?>
</div>


Thanks much for your help

Sheldon
08-04-2008, 03:03 AM
What are you trying to do? You have found some one else's huge pice of code, just to display the contents of a single directory?

You should look in to glob.

With your result, you can use substr() to cut of the file path.

Here is an example using glob and substr.


Have I not already answered and seen about 3 more questions/threads relating to this exact question?

<?php


// DIRECTORY DISPLAY USING GLOB AND A CLEAN PATH OUTPUT.
// IF ALL PERIMATORS ARE EMPTY WILL SCNA DEFAULT DIRECTORY
// '$path' => PATH TO DIRECOTRY TO SCAN
// '$ext' => FILES EXT, IF YOU WANT OT ECLUDE IT, OR ONLY SCAN FOR ONE TYPE OF FILE
// '$start' => APPEND TO START OF OUTPUT LINE EG: '<li>' OR '<div class="list">'
// '$end' => APPEND TO END OF OUTPUT LINE EG: '</li>' OR '</div>\n' => DEFAULT '\n'
function direcotryList($path = "./", $ext = NULL, $start = NULL, $end = "\n"){
$output = "";
$ignore = array(".","..","thumbs.db");
foreach(glob($path ."*". $ext) as $file){
if(is_file($file) and !in_array($file, $ignore)){
$output .= $start . buildLink($file, $path, $ext) . $end . $nl;
}
}
}

// THIS FUNCTION WILL OUTPUT A CLEAN LINK.
// BUILT FROM THE PREVIOUS FUNCTION.
function buildLink($file, $path, $ext = NULL){
$len1 = strlen($path);
$len2 = strlen($file);
$start = ($len1 - $len2);
$ext = ($start + strlen($ext));
$file = substr($link, $start, -$ext);
$name = str_replace(array("_","-"), array(" "," "), $file);
$link = "<a href=\"{$file}\">". ucwords($name) ."</a>";
return $link;
}

// EXAMPLES OF USE
// OUTPUT SIMPLE LINKS OF ALL FILES IN THE CURRENT DIRECTORY.
echo(direcotryList());

// OUTPUT ALL JPG IMAGES IN DIVS
$output = "<div id=\"gallery\">\n";
$output .= direcotryList("images/",".jpg","<div class=\"image\">","</div>\n");
$output .= "</div>\n\n";
echo($output);

?>

kudzugazette
08-04-2008, 05:18 AM
I am using preg_find to display the 10 most recently modified files in the directory.

Sheldon
08-04-2008, 10:50 PM
Ok, This should display the XX number of results in X directory sorted by X ( ASC or DESC ).


<?php



// DIRECTORY DISPLAY USING GLOB AND A CLEAN PATH OUTPUT.
// IF ALL PERIMATORS ARE EMPTY WILL SCNA DEFAULT DIRECTORY
// '$display' => AMOUNT OF RECORDS TO DISPLAY
// '$sort' => DISPLAY ORDER 'SORT_DESC' >< 'SORT_ASC'
// '$path' => PATH TO DIRECOTRY TO SCAN
// '$ext' => FILES EXT, IF YOU WANT OT ECLUDE IT, OR ONLY SCAN FOR ONE TYPE OF FILE
// '$start' => APPEND TO START OF OUTPUT LINE EG: '<li>' OR '<div class="list">'
// '$end' => APPEND TO END OF OUTPUT LINE EG: '</li>' OR '</div>\n' => DEFAULT '\n'
function direcotryList($display = 10, $sort = "SORT_DESC", $path = "./", $ext = NULL, $start = NULL, $end = "\n"){
$return = (int)0;
$output = "";
$ignore = array(".","..","thumbs.db");
if(($count = count($files = glob($path ."*.jpg"))) > 0){
foreach($files as $v){
$filemtime[] = filectime($v);
}
array_multisort($filemtime, $sort, $files);
foreach($files as $file){
if($return <= $display){
if(is_file($file) and !in_array($file, $ignore)){
$output .= $start . buildLink($file, $path, $ext) . $end;
$return++;
}
}else{
break;
}
}
}
return $output;
}

?>

Sheldon
08-05-2008, 01:06 AM
EDIT: There is an error on this line:

if(($count = count($files = glob($path ."*.jpg"))) > 0)
Remove the .jpg surrounding the *

if(($count = count($files = glob($path ."*"))) > 0)

Also array_multisort wont allow a variable to sort by.
Remove the $sort variable from the following line and the function definition, then add it directly in to the code.

array_multisort($filemtime, SORT_DESC, $files);

Too late to edit my previous post.