#1778 Delete one media file - all files with same name deleted

v4.0.2
open-fixed
None
5
2008-11-17
2007-11-03
No

I have in two different media directories files with the same name.

One is deleted (or moved to another directory).
This causes both to be marked for deletion.

Discussion

  • Larry Meaney

    Larry Meaney - 2007-11-08

    Logged In: YES
    user_id=45016
    Originator: NO

    I think I see how this could happen.

    Say you have one file in your main media directory:
    /phpGedView/media/filename.jpg
    and another one in a subdirectory:
    /phpGedView/media/dir/filename.jpg

    When you try to delete the file in the main directory, it runs this sql:
    SELECT * FROM pgv_media WHERE m_file LIKE '%filename.jpg'
    thus marking both files for deletion.

    This problem only occurs when deleting from the main media directory, if you try to delete the file from the subfolder it will run this sql:
    SELECT * FROM pgv_media WHERE m_file LIKE '%dir/filename.jpg'
    which matches the specific file you want it to.

    This is a tough problem. The sql has to use a wildcard because when importing from outside of PGV the path stored in the GEDCOM might look like this:
    c:/files/sources/filename.jpg

    Does anyone see a way to solve this?

     
  • Meliza Amity

    Meliza Amity - 2007-11-08

    Logged In: YES
    user_id=959928
    Originator: YES

    I do not undderstand your last comment: "when importing from outside of PGV the path stored in the GEDCOM might look like this:
    c:/files/sources/filename.jpg".
    Please elaborate.
    The media in my GEDCOM file exported from PAF looks like:
    1 OBJE
    2 FORM jpg
    2 FILE media\pictures\xxx\Per.jpg
    2 TITL Per W
    2 NOTE ...
    I see it both in PAF and in PGV.

    I had the same file name in two directories (media and media/admin)linked to two individuals.
    I deleted the file M65 in media. (I did not delete first the media object.)
    I87 - M64 in media/admin
    I90 - M65 in media

    I see
    Media file successfully deleted.
    Thumbnail file successfully deleted.
    Record I90 successfully updated.
    Record M65 successfully removed from GEDCOM.
    Record M64 successfully removed from GEDCOM.
    Update successful

    According to this I87 is not updated?!?

    I now see on the media tabs of the pages of I87 and I90 the media files M64 and M65 in a red box and an empty blue box.
    For I90 M65 I do not see in the red box the media thumb.
    For I87 I see the M64 thumb.

    For I90 I see also
    ERROR 8: Undefined index: M65
    0 Error occurred on line 1306 of file functions_print_facts.php in function print_main_media
    1 called from line 1246 of file individual_ctrl.php in function print_media_tab
    2 called from line 984 of file individual_ctrl.php in function getTab
    3 called from line 256 of file individual_ctrl.php in function init
    4 called from line 2009 of file individual_ctrl.php in function require_once
    5 called from line 29 of file individual.php

    I now want to undo the changes.
    I do not see I87 in the list to approve changes.

    I undo the 3 other changes.

    File M64 is returned to I87.
    File of M65 was deleted, only the object remained.

    I carried out the same sequence once before.
    I think that the outcome was slightly different.

     
  • John Finlay

    John Finlay - 2007-11-08

    Logged In: YES
    user_id=300048
    Originator: NO

    I think that I have fixed this in the latest SVN 2162. I did a lot of testing and consolidated a LOT of old code. There is still way too much duplicated code in manage media to be to my liking, but I'll leave it for now.

    The way I decided to fix this was to split the filenames on the / and then compare the number of slashes before the query with the number after the query. They should match exactly to make sure that the number of levels match and that no files in the subdirectory are deleted.

    As an example, suppose you have c:/files/filename.jpg and c:/files/sources/filename.jpg on the server and you want to delete the c:/files/filename.jpg. This will cause a query to be generated as with %filename.jpg which will also match the filename in sources. But if we count the / in c:/files/filename.jpg we get 2 and if we count the / in c:/files/sources/filename.jpg we get 3 so they won't match then it won't get deleted.

    This was a difficult problem to solve.

    --John

     
  • John Finlay

    John Finlay - 2007-11-08
    • assigned_to: nobody --> yalnifj
    • status: open --> pending-fixed
     
  • Larry Meaney

    Larry Meaney - 2007-11-08

    Logged In: YES
    user_id=45016
    Originator: NO

    That's a very creative solution John!

    There is one more problem area I thought of but didn't get a chance to add to the case notes here, and I think it might still be a problem.

    Given these three files:
    /media/johnsmith.jpg
    /media/jacksmith.jpg
    /media/smith.jpg

    If you try to delete "smith.jpg", will it delete all three?

     
  • John Finlay

    John Finlay - 2007-11-08

    Logged In: YES
    user_id=300048
    Originator: NO

    Good catch Larry!

    I think that most of the time it wouldn't be a problem because it strips out the "media/" from the query before searching directory and should leave one of the slashes. But since the user can enter the value of the media directory, we can't guarantee that a slash will be there.

    Also an even trickier case is if the files are spelled the same but the case is different:
    /media/smith.jpg
    /media/SMITH.jpg

    Not a problem on Windows because it is case-insensitive, but *nix systems won't know the difference, and our SQL query is also case insensitive.

    But I think I can solve both problems by checking if the filename is exactly the same. I have the exact filename because I have already split the paths on the /. So the check now becomes:
    if (count($rlevels)==count($mlevels) && end($mlevels)==end($rlevels)) {

    I have committed this to SVN 2163.

    --John

     
  • Larry Meaney

    Larry Meaney - 2007-11-09

    Logged In: YES
    user_id=45016
    Originator: NO

    Ah, you're right, there should still be a leading slash in the filename. But I like that extra check you added, it should catch all the edge cases and make absolutely sure nothing extra is deleted.

    Great fix for this tough problem!

    -larry

     
  • Larry Meaney

    Larry Meaney - 2007-11-09

    Logged In: YES
    user_id=45016
    Originator: NO

    Hey John,

    I don't think this is quite right yet.

    When I export a GEDCOM from TMG my media filenames look like this:
    d:/Documents and Settings/ljm/My Documents/ged/sources/beasley/beasley_fred_1876/beasley_fred_1876_beasleymen.jpg

    My "Multi-Media directory levels to keep" is set to "2", so my PGV urls are:
    /phpGedView/media/beasley/beasley_fred_1876/beasley_fred_1876_beasleymen.jpg

    This means that the number of slashes don't match and this code never gets the chance to run:
    if (count($rlevels)==count($mlevels) && end($mlevels)==end($rlevels)) {
    if ($row["m_gedfile"]!=$GEDCOMS[$GEDCOM]["id"]) $onegedcom = false;
    else $xrefs[] = $row["m_media"];
    }

    Would it make sense to bring MEDIA_DIRECTORY_LEVELS into the calculation? This *seems* to work:

    $num_rlevels = count($rlevels);
    if ($num_rlevels > ($MEDIA_DIRECTORY_LEVELS+2)) {$num_rlevels = $MEDIA_DIRECTORY_LEVELS+2;}
    if ($num_rlevels==count($mlevels) && end($mlevels)==end($rlevels)) {
    if ($row["m_gedfile"]!=$GEDCOMS[$GEDCOM]["id"]) $onegedcom = false;
    else $xrefs[] = $row["m_media"];
    }

     
  • John Finlay

    John Finlay - 2007-11-09

    Logged In: YES
    user_id=300048
    Originator: NO

    Hi Larry,

    Since people can have their media directories in multiple places, would it be better to just leave off the +2? Anything greater than the MEDIA_DIRECTORY_LEVELS would be the same on the server anyway.

    if ($num_rlevels > $MEDIA_DIRECTORY_LEVELS) {$num_rlevels =
    $MEDIA_DIRECTORY_LEVELS;}
    if ($num_mrlevels > $MEDIA_DIRECTORY_LEVELS) {$num_mlevels =
    $MEDIA_DIRECTORY_LEVELS;}
    if ($num_rlevels==$num_mlevels) && end($mlevels)==end($rlevels)) {

    What do you think?

    --John

     
  • Larry Meaney

    Larry Meaney - 2007-11-09

    Logged In: YES
    user_id=45016
    Originator: NO

    I don't think that will work; I am pretty sure this if statment will ALWAYS execute:
    if ($num_mlevels > $MEDIA_DIRECTORY_LEVELS) {$num_mlevels = $MEDIA_DIRECTORY_LEVELS;}

    Because mlevels is based on the full path to the media file (including the MEDIA_DIRECTORY, so +1 if your MEDIA_DIRECTORY is "media/") and it also includes the filename (so another +1)

    For example, mlevels for this file:
    media/beasley/beasley_fred_1876/beasley_fred_1876_beasleymen.jpg
    is 4:
    Array ( [0] => media [1] => beasley [2] => beasley_fred_1876 [3] => beasley_fred_1876_beasleymen.jpg )
    (which is MEDIA_DIRECTORY_LEVELS + 2).

    My +2 hack is therefore invalid too, if your MEDIA_DIRECTORY is set to something like "media/gedcom1/" you will need MEDIA_DIRECTORY_LEVELS +3.

    this is a bit complex isn't it :)

     
  • John Finlay

    John Finlay - 2007-11-09

    Logged In: YES
    user_id=300048
    Originator: NO

    What about if we drop the entire counting idea and just check all of the levels up to the media directory level in a loop:

    $match = true;
    $j=0;
    for($i=count($rlevels)-1; $i>=0; $i--) {
    if ($rlevels[$i] != $mlevels[$i]) {
    $match = false;
    break;
    }
    $j++;
    if ($j>$MEDIA_DIRECTORY_LEVELS) break;
    }
    if ($match) {
    if ($row["m_gedfile"]!=$GEDCOMS[$GEDCOM]["id"]) $onegedcom = false;
    else $xrefs[] = $row["m_media"];
    }

    This will check that there is an exact match at each level up to MEDIA_DIRECTORY_LEVELS.

    I've committed this solution. What do you think?

    --John

     
  • Larry Meaney

    Larry Meaney - 2007-11-09

    Logged In: YES
    user_id=45016
    Originator: NO

    Hi John,

    When mlevels is something like this:

    Array ( [0] => media [1] => bitterlich [2] => bitterlich_emil_1857 [3] => bitterlich_emil_1857_marriage_b_2.jpg )

    And rlevels is something like this:

    Array ( [0] => d: [1] => Documents and Settings [2] => ljm [3] => My Documents [4] => ged [5] => sources [6] => bitterlich [7] => bitterlich_emil_1857 [8] => bitterlich_emil_1857_marriage_b_2.jpg )

    then this code:
    if ($rlevels[$i] != $mlevels[$i])

    throws this error:

    ERROR 8: Undefined offset: 8
    0 Error occurred on in function unknown
    1 called from line 1044 of file media.php

    However, this code works for me:
    if ($rlevels[$i] != $mlevels[count($mlevels)-$j-1])

    Does that line work for your test cases?

    -larry

     
  • John Finlay

    John Finlay - 2007-11-09

    Logged In: YES
    user_id=300048
    Originator: NO

    Oops. I forgot to test them switched around. I'll have to track the two sets differently.

    Another new file is in SVN.

    Thanks for you help to test this.

    --John

     
  • Larry Meaney

    Larry Meaney - 2007-11-10

    Logged In: YES
    user_id=45016
    Originator: NO

    looks good John!

     
  • Meliza Amity

    Meliza Amity - 2007-11-11

    Logged In: YES
    user_id=959928
    Originator: YES

    I managed to remove just a media file from the root directory /media.
    After I approved the deletion, I got a red error message that the media object does no longer exist.
    I got rid of the message after I returned to the manage media list of the root directory.

     
  • Meliza Amity

    Meliza Amity - 2007-11-11
    • status: pending-fixed --> open-fixed
     
  • Greg Roach

    Greg Roach - 2008-11-17
    • milestone: --> v4.0.2
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks