0

I have an upload folder that has images inside of it that are named in this format...

10000XXXX-COUNT-DATE-EMPLOYEE-PP-FILEEXTENSION

which looks like this...

100002246-1-2014-05-05-David.Rosales-PP.jpg

Each time a photo is uploaded using PHP I need to scan the files in this directory and find a match for the ID part which is the first 9 digits of the filename.

IF a match is found, I then need to append a number to the COUNT position which is in the number 11 character spot from the left.

The idea is an ID can have 5-6 images. If the ID has 1 image already then the next image should be named 100002246-2-2014-05-05-David.Rosales-PP.jpg and after that another image on a different upload sessions would be 100002246-3-2014-05-05-David.Rosales-PP.jpg so each new image for an ID number will increment by 1 number. You can see I have added the count number at the number 11 character spot.

I am not sure how to best achieve this right now. I cannot use a database so I have to do this during the upload process and scan the directory to find any matches for an image.

Any ideas and example of how I can best do this please?

Something like this for scanning the directory looks promising...

foreach (new DirectoryIterator('.') as $item) {
    echo $item, PHP_EOL;
}

UPDATE - My attempt at a solution so far

<?php
$orderId = $_GET['orderid'];


$dir = new DirectoryIterator('uploads');
$fileMatches = array();

foreach ($dir as $fileinfo) {

    $filenameId= substr($fileinfo->getFilename(), 0, 9);

    if($filenameId === $orderId){
        //store File ID matches in an array
        $fileMatches[] = $filenameId;
    }
    echo $fileinfo->getFilename() . "<br>";
}
$totalImages = count($fileMatches);
echo '<hr>Total Images found for this ID '.$orderId.' = '.$totalImages;
echo '<hr>New count for image would be = '. ($totalImages+1);

?>
Charles
  • 50,943
  • 13
  • 104
  • 142
JasonDavis
  • 48,204
  • 100
  • 318
  • 537

2 Answers2

2

You might be able to use glob() for your purposes. Supposing all pictures are in a directory named imgs:

$user_imgs = count(glob('imgs/*'.$user_id.'*')));

$user_imgs will contain the number of files in imgs that have $user_id in the file name.

You can get more creative with the pattern, if need be. This example just finds all files that have $user_id anywhere in the file name. Up to you how specific you want to be regarding the pattern you are searching for.

UPDATE based on your attempted solution

You can simplify your algorithm to this:

$orderId = $_GET['orderid'];

$all_images = glob('uploads/'.$orderId.'*');

foreach($all_images as $i)
    echo $i . '<br/>';

$totalImages = count($all_images);

echo '<hr>Total Images found for this ID '.$orderId.' = '.$totalImages;
echo '<hr>New count for image would be = '. ($totalImages+1);

UPDATE in consideration of new requirements

$orderId = $_GET['orderid'];

$all_images = glob('uploads/'.$orderId.'*');

$pp = $qc = 0;

foreach($all_images as $i) {
    if (strpos($i, '-PP.')!==false)
        $pp++;
    elseif (strpos($i, '-QC.')!==false)
        $qc++;
}

echo '<hr>Total Images found for this ID '.$orderId.' (PP) = '.$pp;
echo '<hr>New count for image would be = '. ($pp+1);

echo '<hr>Total Images found for this ID '.$orderId.' (QC) = '.$qc;
echo '<hr>New count for image would be = '. ($qc+1);
Mark Miller
  • 7,442
  • 2
  • 16
  • 22
  • Interesting this would be a much simpler hack if it works as right now I am playing with looping over each image with `DirectoryIterator` and then using `substr` and storing matches into a new array and i'm just getting started...I will try this out thanks – JasonDavis May 05 '14 at 22:30
  • Thanks, this works great. My boss has added a new requirement though, perhaps your method is smart enough to expand for this...There are 2 types of images for each OrderID, right before the file extension is a `PP` or else a `QC` like these 2 examples... `uploads/100002057-2014-05-01-David.Rosales-QC.jpg` and ` uploads/100002057-2014-05-01-David.Rosales-PP.jpg` basically I need to do my counter, 1,2,3,4 etc for each type of image meaning `PP` images for an ID will be 1,2,3 and `QC` images for that same ID will also start at ` and go up... – JasonDavis May 06 '14 at 03:35
  • ...so the counter will be separate even though the ID will be the same if that makes sense. The `PP` and `QC` can also be moved to a different position inside of the filename if needed....as long as it is not the first item, the ID should always be first. Appreciate your help I will select your answer as you answered my original question, this is just a mod if you can possibly help – JasonDavis May 06 '14 at 03:39
  • @jasondavis Ok... is it necessary for you to echo out the name of each file? Or do you just need the number for each category? – Mark Miller May 06 '14 at 03:50
  • Well showing each name is just for testing to see it visually for now...this will actually be ran as a new file is being uploaded...so it will need to detect existing files for the same ID number and if they exist then I need to add the 1,2,3,4 etc to the new filename as I am saving the file, so no I should not need to show each filename – JasonDavis May 06 '14 at 03:52
  • This file for the first time `100002057-2014-05-01-David.Rosales-QC.jpg` should actually be saved as `100002057-COUNT1-2014-05-01-David.Rosales-QC.jpg` and the next time a `QC` image is uploaded for that ID number, it should be saved as `100002057-COUNT2-2014-05-01-David.Rosales-QC.jpg` but now if I upload a file for the same ID but with the `PP` ending, then it should start at `1` as well so `100002057-COUNT1-2014-05-01-David.Rosales-PP.jpg` and the next for a `PP` with that same ID will be `100002057-COUNT2-2014-05-01-David.Rosales-PP.jpg` – JasonDavis May 06 '14 at 03:56
  • .,.the word `COUNT` in the filename is not required but it wouldn't hurt to use it either to show what that number is for – JasonDavis May 06 '14 at 03:56
  • That's awesome thanks so much, you probably saved me a couple hours of fiddling with this tonight – JasonDavis May 06 '14 at 04:00
1

To split the string up into logical pieces, you can split and then join it later, once you have manipulated it. Here is something that I've just tested on my machine, and it works.

<?php 
// note explicitly set here, but in wild it might be int
$_GET['orderid'] = '100002246';

if(! isset($_GET['orderid']) || ( isset($_GET['orderid']) && !is_string($_GET['orderid'])) 
  || (isset($_GET['orderid']) && is_string($_GET['orderid']) && !preg_match('/^[0-9]+$/', $_GET['orderid']))) {
    // don't run script, this isn't a valid ID
    die("We didn't have a good name\n");
  }

foreach (new DirectoryIterator('.') as $fileInfo) 
{
    if($fileInfo->isDot()) continue;

    $parts = preg_split('/-/', $fileInfo->getFilename());

    if(count($parts) != 7) 
    {
        echo "Cannot parse this file: ", $fileInfo->getFilename(), PHP_EOL;
        continue;
    }

    $associated_parts = array(
        "id"    => (int)$parts[0],
        "count" => (int)$parts[1],
        "date"  => $parts[2] . '-' . $parts[3] . '-' . $parts[4],
        "name"  => $parts[5],
        "ext"   => $parts[6]
    );

    if($associated_parts['id'] == $id) 
    {
        $associated_parts['count'] = $associated_parts['count'] + 1;
        $new_file = implode('-', $associated_parts);
        rename($fileInfo->getFilename(), $new_file);        
    }
}

foreach (new DirectoryIterator('.') as $fileInfo) 
{
    if($fileInfo->isDot()) continue;
    echo $fileInfo->getFileName(), PHP_EOL;
}
Ryan
  • 14,392
  • 8
  • 62
  • 102