Add icon next to filename - php

I have the following code which sorts files in its current directory:
<?php
$folders = array_filter(glob('*'), 'is_dir');
foreach ($folders as $foldlist) {
echo "<tr><td><img src=\"/index/RESSOURCES/icon/folder.png\"></td><td>{$foldlist}</td><td><img src=\"/RESSOURCES/icon/info.png\"></td></tr>";
}
$files = glob("*.*");
foreach ($files as $filename) {
$type=substr($filename,strrpos($filename,'.')+1);
echo "<tr><td><img src=\"/index/RESSOURCES/icon/{$type}.png\"></td><td>{$filename}</td><td><img src=\"/RESSOURCES/icon/info.png\"></td></tr>";
}
?>
It works, don't worry about that. There is only a minor problem that I've been troubleshooting for the last few days:
If you run my code, you'll see that before every file name, there is an icon. It fetches the right icon by taking the file s format. Cool, right?
But here is my problem:
Lets say I have two files: dummy.zip and dummy.tar.
Both files will fetch "zip.png" and "tar.png" - The two icons are exactly the same. So basically, im making the client load two times the same icon, witch makes my page significally slower. Nothing dramatic? Well, I have over a hundred files right now... Witch pretty much all of them having a different format.
How can I make it so:
if $icon == zip OR tar OR gz LOAD zip.png?
Cheers.

After your line
$type = substr($filename,strrpos($filename,'.')+1);
and before
echo "<tr><td><img src=\"/index/RESSOURCES/icon/{$type}.png\"></td><td>{$filename}</td><td><img src=\"/RESSOURCES/icon/info.png\"></td></tr>";
you may just add the following code
if($type == 'zip' || $type == 'tar' || $type == 'gz') {
$type = 'zip';
}
It will load zip.png for all the three cases

Related

How do I move a specified number of files automatically from one folder to another using PHP? (for use in WordPress plugin)

Using a WordPress plugin, I have an image carousel that displays all files within a specified folder.
I only want to display the last 24 images from that folder. One way I thought I could do this without editing the original plugin is have all files from the previous day move to a new folder when the first photo from the next day arrives. The file names contain a time stamp, because of this, I can't specify actual file names, just the type of file.
Unfortunately, I am completely new to PHP and Server Side Scripting and would appreciate any advice on how to solve this issue.
I believe you don't have to move the files, just read them and sort by date.
here's a conceptual how to, untested.
$files =[];
if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$files[filemtime($file)] = $file;
}
}
closedir($handle);
// sort in reverse order
krsort($files);
for($i =0; $i < 24; $i++) {
$file = $files[$i]
echo "<img src='".$file."' />";
}
}
good luck
Ok, You want to display only last 24 images from that folder.
You can get name of last 24 images by their modification time.
$filelist = glob("/path/to/your_dir/*.{jpg,JPG,PNG,png,jpeg,JPEG}", GLOB_BRACE);
In php run a foreach loop for all the files in that directory, ,
$i = 0;
foreach($filelist as $key => $file){
$temp_arr[$i]['mtime'] = filemtime($file);
$temp[$i]['filename'] = $file;
$i++;
}
Then you can sort $temp_arr to retrive 24 latest images based on mtime.

PHP - SplFileObject - Wrong output for second line when using seek() method

Go to UPDATE to read what's the actual problem now. Old question was already resolved with the first answer submitted by Bert Peters.
OLD QUESTION:
I have few files named as file.1.txt, file.2.txt, file.3.txt, ... I'm reading first file with SplFileObject and using foreach loop to iterate through its content:
$file = new SplFileObject("file.1.txt");
foreach ($file as $row) {
// ...
}
Other files may be or may not be read, depending on the contents of the first file I'm reading. In all cases there should be only one file of others (file.2.txt or file.3.txt) which may be used in the next step. So somewhere inside foreach loop there is if statement which handles this.
All files have the same structure, so there comes the problem. I wouldn't like to create new foreach for reading next file - as I wrote it may not be needed at all, so I would like to use existing foreach instead of writing new one. Is there any possibility to overwrite $file variable with the contents of other file and iterate over it with using only one foreach or any other loop? For example:
foreach ($file as $row) {
// ...
if ($contentContainsSomething) {
$file = new SplFileObject("file.2.txt");
// somehow reset foreach to read file.2.txt from start
}
}
I wouldn't like to use goto statement to solve this problem. The recursion seems to be appropriate solution, but if there's a way to change object in loop on the fly, I would prefer this solution.
UPDATE:
As mentioned in "old question" all used files (file.1.txt, file.2.txt, ...) have the same structure, so that's why I wouldn't like to write more same loops and copy code. Instead I used code from #Danack (suggested by him on SO chat) which is already a part of solution. Here's the basic code for reading more files without any upgrade I need:
$path = "file.1.txt";
$whileCounter = 0;
while ($path != null) {
$file = new SplFileObject($path);
$file->setFlags(SplFileObject::READ_CSV);
$file->setCsvControl("\t");
$path = null;
foreach ($file as $rowKey => $row) {
// echo row }
$path = "file.2.txt";
if ($whileCounter > 0) {
break; // solution to stop loop, just for now
}
$whileCounter++;
}
So this code is working without any problem and outputs the file's lines as expected. The problem is when I would like to read next line of file with seek() method, because I would like to make decision on some information which is appended to each next line. So if I use seek($rowKey + 1) which helps me to get next line data (I use $file->current() when line is changed) and after that I call seek($rowKey) to get to previous line, then next file will output first line twice and second line will be missed. The third line and all after then are printed well. This is the problem achieved with the code below:
$path = "file.1.txt";
$whileCounter = 0;
while ($path != null) {
$file = new SplFileObject($path);
$file->setFlags(SplFileObject::READ_CSV);
$file->setCsvControl("\t");
$path = null;
foreach ($file as $rowKey => $row) {
if ($whileCounter > 0) {
var_dump($row);
echo "<br>";
}
$file->seek($rowKey + 1);
if ($file->valid()) {
$file->seek($rowKey);
} else {
var_dump($row);
echo "<br>";
$path = "file.2.txt";
}
}
$whileCounter++;
}
If you apply custom .csv files (with at least five non-empty lines) instead of file.1.txt and file.2.txt, you will see that second and third output are the same (second and third output are first and "second" lines of file.2.txt). What could be wrong here?
There is not. Foreach uses an iterator over your $file variable, and that iterator continues to be valid even though you changed the value of $file.
Or, to put this in another way, foreach will continue to look at the previous contents of $file, regardless of what you do with it afterwards. This is because $file is not actually the SplFileObject, but rather a reference to it, and the reference is used by foreach.

search and delete unused images in articles with php

I have been working on some project and through time it got messed up with images which I tested it, so now I want to make a script which is going to search in articles img tags and find the img name (artiles are stored in mysql with attribute 'text') after scanning the folder where images are stored if they are not in any article included then to delete those images (unused images). Has anyone done this before so I could see an example or any good approach about this case?
Here's what you'll need to do what you want:
Loop through your directory of files (if they are on the filesystem):
if ($handle = opendir('/path/to/files')) {
echo "Directory handle: $handle\n";
echo "Entries:\n";
/* This is the correct way to loop over the directory. */
while (false !== ($entry = readdir($handle))) {
echo "$entry\n";
}
/* This is the WRONG way to loop over the directory. */
while ($entry = readdir($handle)) {
echo "$entry\n";
}
closedir($handle);
}
Ref. http://php.net/readdir
Loop through your files (if they are on the database):
Ref. http://www.php.net/manual/en/mysqli.query.php
Compare file names (obvious once you are looping through your resource).
Delete unused images like so http://www.php.net/unlink
Approach is simple
Query database and get list of all image URLs - add to an array
Loop through each folder that contains images and make an array of every image on the site/
here is how to find all items that are in one array but not another (may be a better answer more specific to you - array_Intesect is what you need.
with the new array simply loop through the list and delete the files.
All of the above you can search individually and then string them together.
I would recommend backing everything up before trying!!!!
I recently came accross such thing where I wanted to remove unused files that users left behind / change the profile picture but they were stored on the webserver. To fix this I used this :
$images = scandir("uploads", 1);
foreach ($images as $itemlc)
{
$res=mysql_query("SELECT * FROM company WHERE c_logo='$itemlc'");
$count = mysql_num_rows($res);
$res2=mysql_query("SELECT * FROM users WHERE u_logo='$itemlc'");
$count2 = mysql_num_rows($res2);
if($count == 1)
{
echo $itemlc; echo " exists <br><br>";
}
else if ($count2 == 1)
{
echo $itemlc; echo " exists <br><br>";
}
else{ $file_path = 'uploads/'; $src=$file_path.$itemlc; #unlink($src); }
}
Hope this helps if there is someone who needs this!

PHP readir results - trying to sort by date created and also get rid of "." and ".."

I have a double question. Part one: I've pulled a nice list of pdf files from a directory and have appended a file called download.php to the "href" link so the pdf files don't try to open as a web page (they do save/save as instead). Trouble is I need to order the pdf files/links by date created. I've tried lots of variations but nothing seems to work! Script below. I'd also like to get rid of the "." and ".." directory dots! Any ideas on how to achieve all of that. Individually, these problems have been solved before, but not with my appended download.php scenario :)
<?php
$dir="../uploads2"; // Directory where files are stored
if ($dir_list = opendir($dir))
{
while(($filename = readdir($dir_list)) !== false)
{
?>
<p><a href="http://www.duncton.org/download.php?file=login/uploads2/<?php echo $filename; ?>"><?php echo $filename;
?></a></p>
<?php
}
closedir($dir_list);
}
?>
While you can filter them out*, the . and .. handles always come first. So you could just cut them away. In particular if you use the simpler scandir() method:
foreach (array_slice(scandir($dir), 2) as $filename) {
One could also use glob("dir/*") which skips dotfiles implicitly. As it returns the full path sorting by ctime then becomes easier as well:
$files = glob("dir/*");
// make filename->ctime mapping
$files = array_combine($files, array_map("filectime", $files));
// sorts filename list
arsort($files);
$files = array_keys($files);

Multiple Random Includes from Directory with Sub-Directories

I have a directory containing sub directories which each contain a series of files. I'm looking for a script that will look inside the sub directories and randomly return a specified number of files.
There are a few scripts that can search a single directories (not sub folders), and other scripts that can search sub folders but only return one file.
To put a little context on the situation, the returned files will be included as li's in an rotating banner.
Thanks in advance for any help, hopefully this is possible.
I think I've got there, not exactly what I set out to achieve but works good enough, arguably better for the purpose, I'm using the following function:
<?php function RandomFile($folder='', $extensions='.*'){
// fix path:
$folder = trim($folder);
$folder = ($folder == '') ? './' : $folder;
// check folder:
if (!is_dir($folder)){ die('invalid folder given!'); }
// create files array
$files = array();
// open directory
if ($dir = #opendir($folder)){
// go trough all files:
while($file = readdir($dir)){
if (!preg_match('/^\.+$/', $file) and
preg_match('/\.('.$extensions.')$/', $file)){
// feed the array:
$files[] = $file;
}
}
// close directory
closedir($dir);
}
else {
die('Could not open the folder "'.$folder.'"');
}
if (count($files) == 0){
die('No files where found :-(');
}
// seed random function:
mt_srand((double)microtime()*1000000);
// get an random index:
$rand = mt_rand(0, count($files)-1);
// check again:
if (!isset($files[$rand])){
die('Array index was not found! very strange!');
}
// return the random file:
return $folder . "/" . $files[$rand];
}
$random1 = RandomFile('project-banners/website-design');
while (!$random2 || $random2 == $random1) {
$random2 = RandomFile('project-banners/logo-design');
}
while (!$random3 || $random3 == $random1 || $random3 == $random2) {
$random3 = RandomFile('project-banners/design-for-print');
}
?>
And echoing the results into the container (in this case the ul):
<?php include($random1) ;?>
<?php include($random2) ;?>
<?php include($random3) ;?>
Thanks to quickshiftin for his help, however it was a little above my skill level.
For info the original script which I changed an be found at:
http://randaclay.com/tips-tools/multiple-random-image-php-script/
Scrubbing the filesystem every single time to randomly select a file to display will be really slow. You should index the directory structure ahead of time. You can do this many ways, try a simple find command or if you really want to use PHP my favorite choice would be RecursiveDirectoryIterator plus RecursiveIteratorIterator.
Put all the results into one file and just read from there when you select a file to display. You can use the line numbers as an index, and the rand function to pick a line and thus a file to display. You might want to consider something more evenly distributed than rand though, you know to keep the advertisers happy :)
EDIT:
Adding a simple real-world example:
// define the location of the portfolio directory
define('PORTFOLIO_ROOT', '/Users/quickshiftin/junk-php');
// and a place where we'll store the index
define('FILE_INDEX', '/tmp/porfolio-map.txt');
// if the index doesn't exist, build it
// (this doesn't take into account changes to the portfolio files)
if(!file_exists(FILE_INDEX))
shell_exec('find ' . PORTFOLIO_ROOT . ' > ' . FILE_INDEX);
// read the index into memory (very slow but easy way to do this)
$aIndex = file(FILE_INDEX);
// randomly select an index
$iIndex = rand(0, count($aIndex) - 1);
// spit out the filename
var_dump(trim($aIndex[$iIndex]));

Categories