Support » Developing with WordPress » setcookie fails inside shortcode

  • Resolved petesalerno

    (@petesalerno)


    I am not able to set a cookie from inside a shortcode. inside my test WordPress site [ redundant link removed ] the setcookie returns FALSE. Inside a non-WordPress environment(apps.stratusconcept.com/zohotest/cook.php) the function works fine.

    Here is the code for the basic function:

    add_shortcode("SC-PVT", "sc_pvt_sc");
    
    function sc_pvt_sc(){
       if(isset($_COOKIE['scvttest'])) {
        	echo "Cookie is set!<br>";
       } else {
    	echo "Cookie is NOT set!<br>";
    	 $res = setcookie("scvttest","1234",0,"/",$_SERVER['HTTP_HOST']);
             if ($res){
                echo "-- TRUE --";
             } else {
               echo "-- FALSE --";
            }
       }
    }
    • This topic was modified 1 month, 3 weeks ago by Jan Dembowski. Reason: Formatting

    The page I need help with: [log in to see the link]

Viewing 10 replies - 1 through 10 (of 10 total)
  • Cookies have to be sent before any page content, so your shortcode handler function is too late to set a cookie.
    https://www.php.net/manual/en/function.setcookie.php

    Moderator Steve Stern

    (@sterndata)

    Support Team Volunteer

    Note that shortcodes cannot echo content. Shortcodes return a string to be displayed. Echoing may cause issues, too.

    Moderator bcworkz

    (@bcworkz)

    Any WP action that fires before page output can be used to setcookie(). “wp_headers” action is when other WP header data is sent. “init” action will be fine as well. The problem is you don’t know then if the shortcode is being used. If you must set cookies after output has started you need to do so via JavaScript.

    @joyously Thanks, that was my fear.

    @bcworkz My problem is I need to set the cookie only for the specific page. There will be a set of 4 or 5 cookies unique to different pages. So I can’t have it fire before init. But won’t JavaScript have the same problem? The page will be loaded before the script fires.

    @sterndata Yes, the code is just for illustrating the problem. In the plugin, output will be in the returned variable.

    Setting the cookie in PHP has to happen before any headers are sent to the client.
    But if you do it in javascript, the whole page is already at the client before the JS runs. The subsequent request to the server will contain the cookie (visible to PHP). So if the PHP checks for the cookie in the shortcode handler, not finding one indicates first use.

    This got me thinking.

    If is_page will identify the page in an action for wp_headers I could do it there.

    I tried this without luck:

    add_action( 'init', "sc_set_timer_cookie", 1);
    function sc_set_timer_cookie() {
    	if (is_page(434)) {
    		if(!isset($_COOKIE["myCookie"])) {
    			setcookie( "myCookie", "1234", $expire,"/",$_SERVER['HTTP_HOST'] );
    			}
    		}
    	}
    	return ;
    }

    Note: the test page is ‘https://lostfornever.com/?p=434&#8217;

    • This reply was modified 1 month, 3 weeks ago by petesalerno.
    Moderator bcworkz

    (@bcworkz)

    When “init” fires, the query has not been parsed yet, so is_page() is ineffective there. The order that actions more or less fire is listed at
    https://codex.wordpress.org/Plugin_API/Action_Reference

    It looks like “pre_get_posts” might meet you needs. I’m not sure is_page() is valid yet, but you can get the requested page name from the “pagename” query var, provided you use pretty permalinks.

    If you need to go the JS route, the usual “wp_enqueue_scripts” is also late enough to know what specific page is requested through “pagename”. is_page() will even work by then.

    I ended using posts_selection.
    Thanks everyone for the help.

    Thanks

Viewing 10 replies - 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.