0

I have two php documents that has this same logic. One document is "uploader.php, which writes to the xml once file is upload. The other document is "modifier.php", which writes to the xml once file the is removed. I have two issue with this logic. First issue is deleting last item in the xml list. It doesn't delete the last item and also duplicates the second to last items. Second issue is with it is logging a error on my "uploader.php".

$xml_generator = simplexml_load_file("../file.xml");

if ( $handle = opendir( $path_to_image_dir ) )
{
    while (false !== ($file = readdir($handle)))
    {
        if ( is_file($path.'/'.$file) && $file != "." && $file != ".." && $file != "Thumb.db" && $file != "Thumbs.db" && $file != ".DS_Store" )
        {
            $fileID = $i++;
            list( $width, $height ) = getimagesize($path.'/'.$file);
            $oldImage = $xml_generator->xpath('//images/image[id="'.$fileID.'"]')[0];
            if (!isset($oldImage))
            {
                $image = $xml_generator->addChild('image');
                $image->addChild('id', $fileID);
                $image->addChild('name', $file);
                $image->addChild('width', $width);
                $image->addChild('height', $height);
                $image->addChild('description', '-');
            }
            else
            {
                $oldImage->name = $file;
                $oldImage->width = $width;
                $oldImage->height = $height;
            }
        }
    }
    closedir($handle);
}

$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml_generator->asXML());
echo $dom->save('../file.xml');

Example of the First Issue

Image2.jpg is last item on the list. If I were to delete Image2.jpg, second to last item get duplicated while Image2.jpg remains on XML Document.

<image>
 <id>9</id>
 <name>Image1.jpg</name>
 <width>2551</width>
 <height>1435</height>
 <description>-</description>
</image>
<image>
 <id>10</id>
 <name>Image1.jpg</name>
 <width>2551</width>
 <height>1435</height>
 <description>-</description>
</image>
<image>
 <id>11</id>
 <name>Images2.jpg</name>
 <width>612</width>
 <height>612</height>
 <description>-</description>
</image>

Second Issue is Error Msg .

Undefined offset: 0 in uploader.php on line $oldImage = $xml_generator->xpath('//images/image[id="'.$fileID.'"]')[0];

I think both of these issues are related to the same problem, please help me solve this problem. Thanks!

Delete Code- this code can delete any item except for the last item on the list.

if(isset($_POST['delete'])){
    foreach($_POST['file'] as $file) {
        if(isset($file)) {
            if (unlink($path."/".$file)) {
                echo "Delete the file: $file<br />";
               if (!empty($_SERVER['HTTP_REFERER'])){
                    header("Location: " . $_SERVER['HTTP_REFERER']);
                } else {
                   echo "No referrer.";
                }
            } else {
                echo "Didn't manage to delete the file: $file<br />";
            }
        }
    }
    // very top code goes here.
}
Tierendu
  • 29
  • 4

1 Answers1

0

However this approach would fail in case images can have the same name or be equal which would be better if you generate a unique name for each uploaded image so it doesn't collide.

Change this line:

$oldImage = $xml_generator->xpath('//images/image[id="'.$fileID.'"]');
if (!isset($oldImage))

To:

$oldImage = $xml_generator->xpath('//images/image[name="'.$file.'"]');
if (count($oldImage) == 0)

To avoid the notices, change this:

else
{
    $oldImage->name = $file;

To:

else
{
    $oldImage = $oldImage[0];
    $oldImage->name = $file;

At your delete file you will have to exclude the element so it doesn't replicate.

Here is an example:

$filename = '../file.xml';
$xml = simplexml_load_file($filename);
if(isset($_POST['delete']))
{
    $deleted = 0;
    foreach($_POST['file'] as $file)
    {
        if(isset($file))
        {
            $image = $xml->xpath("//images/image[name='$file']");
            if (!empty($image))
            {
                if (unlink($path."/".$file))
                {
                    $deleted++;
                    $dom=dom_import_simplexml($image[0]);
                    $dom->parentNode->removeChild($dom);
                    echo "Delete the file: $file<br />";
                    if (!empty($_SERVER['HTTP_REFERER']))
                    {
                        header("Location: " . $_SERVER['HTTP_REFERER']);
                    }
                    else
                    {
                        echo "No referrer.";
                    }
                }
                else
                {
                    echo "Didn't manage to delete the file: $file<br />";
                }
            }
            else
            {
                echo "File not found: $file<br />";
            }
        }
    }
    // Avoid unnecessary saving the file
    if ($deleted > 0)
    {
        $dom = new DOMDocument('1.0');
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = true;
        $dom->loadXML($xml->asXML());
        $dom->save($filename);
    }
}

Keep in mind that this will also prevent people from deleting a file that does not exist on the XML as if they change the POST request to something else it would not.

Prix
  • 19,417
  • 15
  • 73
  • 132
  • @Tierendu take a look again I have updated the code to correct an issue on the delete file. – Prix Jul 18 '13 at 23:07
  • Hi @Prix, I'm using your latest code example, but it doesn't delete a file from the XML, instead it goes to `Didn't manage to delete the file:` statement. I must be doing something wrong. I just want to update you on what is going on. As always thank you for your help. – Tierendu Jul 19 '13 at 00:27
  • @Tierendu either the file doesn't exist or you don't have permission to delete the file as it is failing on the `unlink`, you could try to use [**`file_exists`**](http://stackoverflow.com/a/7991445/342740) or place this [**`print_r(error_get_last());`**](http://www.php.net/manual/en/function.error-get-last.php) below your `echo "Didn't...` so see what error it tells you. – Prix Jul 19 '13 at 00:48
  • @Tierendu also what is the content of `$_POST['file']` could you update a `print_r($_POST['file']);` – Prix Jul 19 '13 at 00:55
  • @Tierendu just notice `// very top code goes here.` on your code with the above you will not need to run the top code unless you have new files to update and you should definitively consider migrating to MySQL your setup is starting to get really messed up and even you're having difficult with it. – Prix Jul 19 '13 at 01:07
  • Sorry @Prix, I didn't start project. Someone else made this project half way and gave it to me. Since I'm new to PHP, mostly experimenting and debug for me. You just notice something I was experimenting. I'm away from the project files. I will try all of your suggestions ASAP tomorrow. – Tierendu Jul 19 '13 at 01:47
  • I was missing `$path = '../imageFolder';` that is why it didn't work. Thank you for your hard work. – Tierendu Jul 19 '13 at 17:05