0

At the top of the page I get a url:

$posturl = $_GET['posturl'];

Works, I got the URl.

The I have a series of checkboxes to delete attachments within a form post:

<form action="" method="post">
    <?php
        $attachments = get_posts(array( 
            'post_type' => 'attachment',
            'numberposts' => -1,
            'post_status' =>'any',
            'post_parent' => $_GET['post_id']
        ));
        if ($attachments) {
            foreach ( $attachments as $attachment ) {
                $myNewImg = wp_get_attachment_url( $attachment->ID );
                $pathtofile = $myNewImg;
                $info = pathinfo($pathtofile);
                if ( ($info["extension"] == "jpg") || ($info["extension"] == "png")  || ($info["extension"] == "JPG")  || ($info["extension"] == "jpeg")  || ($info["extension"] == "gif") ) { ?>
                    <img src="<?php echo $myNewImg; ?>" class="bnr_img img-fluid mx-auto d-block" alt="">
                    <input type="checkbox" class="img_delete" name="img_delete[]" value="<?php echo $attachment->ID; ?>">
                <?php } else { ?>
                    <video src="<?php echo $myNewImg; ?>" controls></video>
                    <input type="checkbox" class="img_delete" name="img_delete[]" value="<?php echo $attachment->ID; ?>">
                <?php }
            }
        }
    ?>
    <input class="btn btn-dark" type="submit" name="delete_media" value="Delete media">
</form>

All works fine, I get the media attachments and a checkbox next to it:

I now want to delete media files checked, so they're an array (img_delete[]) so I do:

<?php
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        if (isset($_POST['delete_media'])) {
            foreach($_POST['img_delete'] as $value) {
                wp_delete_attachment( $value, true);
            } 
            header('Location: '.$posturl);
        }
    }
?>

It's ok but:

  1. page doesn't refresh
  2. page stays there but it only shows one item (even tho 2 have been deleted)
  3. if i refresh the page, then I see both have been deleted

So basically I'm trying to redirect the page so that user sees the live page without media attachments.

rob.m
  • 9,843
  • 19
  • 73
  • 162
  • 1
    What sense does it make to try and redirect _inside_ the loop? You want to process _all_ of your deletions first, and then redirect _afterwards_. – CBroe Nov 03 '22 at 09:01
  • Should rather be using https://developer.wordpress.org/reference/functions/wp_redirect/ to begin with, in a WP environment. – CBroe Nov 03 '22 at 09:03
  • _"Works, I got the URl."_ - and that is also still the case, _after_ you submitted your form? – CBroe Nov 03 '22 at 09:04
  • @CBroe no, as i wrote the URL is at the top of the page – rob.m Nov 03 '22 at 09:06
  • @CBroe that's correct, the redirect there was a mistake, but the issue remains. – rob.m Nov 03 '22 at 09:07
  • So you _don't_ have it, at the point where you are actually trying to redirect _to_ it then? In that case, how'd you expect it to work then ...? – CBroe Nov 03 '22 at 09:08
  • @CBroe yes I have it, why you say no? I'm getting the URL from GET at the very beginning of the page, I do have the $url, I also just changed the line to wp_redirect( $posturl ); while it makes sense to use that instead of header, the result is the same – rob.m Nov 03 '22 at 09:10
  • 1
    The description is not clear. Which file does the code belong to? The form doesn't have an action value, so where/how do you post it? How is posturl set? Why do you need to redirect? Using include is more reasonable. Please note header or wp_redirect should be called in the very front of the code, and your browser may refuse to redirect to the same url. – shingo Nov 03 '22 at 09:40
  • @shingo the file is edit_.php. The form action isn't there but there is the redirect which should work anyhow and I post it to the $posturl where it redirects. Why should I use include? For what? The wp_redirect and header is working on another part. – rob.m Nov 03 '22 at 09:48
  • @shingo basically it works, but it doesn't redirect. But the main issue (and the reason why I want it to redirect) is that after I delete the files, the page stays there and shows again the file but if I manually refresh the page then the files are gone. So it's like caching somehow – rob.m Nov 03 '22 at 09:52
  • This "anyhow" is important, because html's original post method should bring you to the new page where form's action is, and you need show the result content in that page (this is what I mean using include). If you send the form by something like `fetch`, the redirect method won't work. – shingo Nov 03 '22 at 10:09
  • @shingo i do the exact same thing but to upload new image, on the same page but with a different form and the redirect works. So this is very strange tbh – rob.m Nov 03 '22 at 10:33
  • @shingo come to the chat please, I'll better show it to you – rob.m Nov 03 '22 at 10:34
  • @shingo just to me it sure, I did put now the link within the action, what it does is now to redirect to that page but ti doesn't even delete them this way – rob.m Nov 03 '22 at 10:44

3 Answers3

1

Whenever you want to redirect using a header() in PHP, you should always exit() afterwards as explained here.

Also, make sure you are redirecting before any output is being sent. Otherwise you will end up with headers already sent warnings and the redirect will not work.

Also, for this, you should be using wp_safe_redirect() or wp_redirect() for this:

<?php
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        if (isset($_POST['delete_media'])) {
            foreach($_POST['img_delete'] as $value) {
                wp_delete_attachment( $value, true);
            } 

            if ( wp_safe_redirect( $posturl ) ) {
                exit;
            }
        }
    }
?>
Cornel Raiu
  • 2,758
  • 3
  • 22
  • 31
  • i did try it, basically if i have a video and an image, then i click delete, the page refreshes but doesn't redirect and it shows the video only while the image is deleted. yet if i manually refresh then both are gone. It's like the video is taking more time to be deleted and the redirect doesn't work. It might be a stupid thing what I've just said but i have not clue why otherwise. On the same page i have a similar code but to upload, and that works fine – rob.m Nov 03 '22 at 11:04
  • @rob.m what if you remove the foreach? does it redirect? – Cornel Raiu Nov 03 '22 at 11:09
  • no, it doesn't even delete it. It's an array remember name="img_delete[]" – rob.m Nov 03 '22 at 11:12
  • are you working with `WP_DEBUG = true`? it might be a `headers already sent` issue – Cornel Raiu Nov 03 '22 at 11:14
  • @rob.m I was saying to completely remove the foreach and the delete statement to see if the redirect works without the delete. That will exclude the chance of a slow delete or anything like that. – Cornel Raiu Nov 03 '22 at 11:20
  • actually no, the redirect isn't working after removing the foreach. very strange tho, it does work on the other code block but with update – rob.m Nov 03 '22 at 11:22
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/249274/discussion-between-rob-m-and-cornel-raiu). – rob.m Nov 03 '22 at 11:28
0
<?php
    if($_SERVER['REQUEST_METHOD'] === 'POST'){
        if(isset($_POST['delete_media'])){
            foreach($_POST['img_delete'] as $value) {
                wp_delete_attachment( $value, true);
            } 
                wp_redirect($posturl); 
        
        }
    }
?>
-2
<?php
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        if (isset($_POST['delete_media'])) {
            foreach($_POST['img_delete'] as $value) {
                wp_delete_attachment( $value, true);
            } 
            header('Location: '.$posturl);
        }
    }
?>

you can use simple javascript for this like below -

<?php
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        if (isset($_POST['delete_media'])) {
            foreach($_POST['img_delete'] as $value) {
                wp_delete_attachment( $value, true);
            } 
            ?>
            <script>location.reload();</script>
            <?php
        
        }
    }
?>
  • that will loop the reload forever tho – rob.m Nov 03 '22 at 11:01
  • `location.reload()` will reload with the POST data as shown here: https://stackoverflow.com/questions/570015/how-do-i-reload-a-page-without-a-postdata-warning-in-javascript – Cornel Raiu Nov 03 '22 at 11:12