• Hello,

    I have a big problem with a plugin I´m writing:
    The visitor should be forwarded to a newsletter registration page, if he visits a post within a blocklist. Unfortunately the forwarding does not work for guests, but when I am logged in, everything works as it should be. The guests only see the 404 page.
    The posts, on which this redirect should be fired, are in „draft“ status!

    public function newsletter_lock_redirect(){
            if (is_single()) {
    	        $cid = $this->nse_get_campaign_id();
    
    	        if(isset($_GET['origin']))
    	        	$origin = filter_var($_GET['origin'], FILTER_SANITIZE_STRING);
    
                global $post;
                global $wpdb;
    	   
    	    $post_tags = get_the_tags($post->ID);
    	            if (!$post_tags)
    	                return;
    
    	            $post_tags_array = json_decode(json_encode($post_tags), true);
    	            if (!$this->in_array_r($this->tag_name, $post_tags_array))
    	                return;
    
    	            $query = 'SELECT * FROM '.$wpdb->newsletter_lock.' WHERE lock_postid = '.$post->ID.' AND lock_status = 1';
    	            $locked = $wpdb->get_row($query, OBJECT);
    
    	            if(empty($locked))
    	                return;
    
    	            if($locked->lock_status == "0")
    	                return;
    
    	            $permalink = get_post_permalink($this->location) . "&cid=" . $cid . "&origin=nl_locked";
    	            wp_safe_redirect( $permalink, $this->status );
    	            exit;
            }
        }
    
    add_action('template_redirect', array($this->public, 'newsletter_lock_redirect'), 10, 2);
Viewing 5 replies - 1 through 5 (of 5 total)
  • Moderator bcworkz

    (@bcworkz)

    It would be because guests are not allowed to see draft posts. I don’t think your callback is even called for guests, their request goes straight to a 404 response.

    Why are the posts saved as drafts? You could probably publish them and manage whatever the reason for drafts some other way.

    Thread Starter nightillusions

    (@wdjac)

    The draft status is required, because of other plugin logic.

    When I looked inside template-loader.php, where the hook is fired, I saw that this hook is before the 404 question elseif ( is_404() && $template = get_404_template() ) :.

    I also tried to use the “wp” hook:

    This hook is one effective place to perform any high-level filtering or validation, following queries, but before WordPress does any routing, processing, or handling.

    But for my plugin logic, it is highly needed to get the post ID at this moment. Do you have any solution for this?

    Thanks for your advice!

    Thread Starter nightillusions

    (@wdjac)

    Okay I think this is a possible solution, but it feels kind of ugly:

    /**
         * Redirect if is a single page and newsletter tag is set
         */
        public function newsletter_lock_redirect(){
    	    global $wp_query;
    
    	    if($wp_query->is_404()) {
    
    		    $page = get_page_by_path( $wp_query->query_vars['name'], OBJECT, 'post' );
    		    if ( $page->post_status == 'draft' ) {
    			    $wp_query->is_404 = false;
    			    header("HTTP/1.1 200 OK");
    
    			    $cid = $this->nse_get_campaign_id();
    
    			    global $wpdb;
    
    			    $post_tags = get_the_tags( $page->ID );
    			    if ( ! $post_tags ) {
    				    return;
    			    }
    
    			    $post_tags_array = json_decode( json_encode( $post_tags ), true );
    			    if ( ! $this->in_array_r( $this->tag_name, $post_tags_array ) ) {
    				    return;
    			    }
    
    			    $query  = 'SELECT * FROM ' . $wpdb->newsletter_lock . ' WHERE lock_postid = ' . $page->ID . ' AND lock_status = 1';
    			    $locked = $wpdb->get_row( $query, OBJECT );
    
    			    if ( empty( $locked ) ) {
    				    return;
    			    }
    
    			    if ( $locked->lock_status == "0" ) {
    				    return;
    			    }
    
    			    $permalink = $this->location . "?cid=" . $cid . "&origin=nl_locked";
    			    wp_safe_redirect( $permalink, $this->status );
    			    exit;
    		    }
    	    }
        }
    add_action('wp', array($this->public, 'newsletter_lock_redirect'));

    Now guests being redirected and admins not. But for me this is okay.
    What do you think?

    Moderator bcworkz

    (@bcworkz)

    Hijacking 404s is not that unusual, it’s essentially just another query property that decides what template to use. If it works for you, go for it. Admins are able to get there through other means and do not need that UX applied to them.

    I think you may want to add $page && before checking if the status == draft to avoid logging warnings when $page is assigned null. Other than that, it looks OK.

    Thread Starter nightillusions

    (@wdjac)

    Thank you for your advice!

    I think you may want to add $page && before checking if the status == draft to avoid logging warnings when $page is assigned null.

    Fully right 😉 Thanks!

Viewing 5 replies - 1 through 5 (of 5 total)

The topic ‘Redirect before 404’ is closed to new replies.