Alternative to Dynamic Cookie Names

@m_hutley Ok I adjusted with the comma included like this:

Cookies.get('shown_offer') + ',' + offerid;

That is/was just an example of the new offer that was showed

You still need to catch the result - because what you want to do (when itā€™s the right time to do it, is actually:

<script>
var offerid = 1; //this number will actually be set by PHP in the end.
var heyineedtocatchthistouseit = Cookies.get('shown_offer') + "," + offerid;
Cookies.set('shown_offer', heyineedtocatchthistouseit, { expires: 1000 });
</script>

I know that :slight_smile:
I think I start to understand the principle. I should have created a Variable from the old Cookie + the new offerid as well. But now the value in the console shows is like this:

0%2C1

%2C is the URL encoded form of a comma. 2C is the Hex value for decimal value 44, which on the ASCII table is a comma. the % tells the parser ā€œHey, the next 2 characters are some Hex for decoding.ā€

Iā€¦ wasnt aware that Cookies URLEncoded their data, though it makes sense. It does mean your PHP will either need to urldecode the string before exploding, or exploding on the literal string ā€œ%2Cā€. Either works.

@m_hutley O.k. understand. But since this is a JS varaible how do I get that to PHP to urldecode or to explode the literal string

Itā€™s a cookie. the browser automatically submits cookies when it sends its request - You dont need to do anything to ā€˜get itā€™ to PHP, it will reside in the $_COOKIE superglobal when the PHP script starts on request (next page load).

@m_hutley So just to be clear so the Modal class and Controller class should be something like this:

In Model class:

public function get_offer($sanitized)
{
	$sql	=  "SELECT *
		         FROM `offers`
		        WHERE `isActive` = 1
                  AND `offer_id` NOT IN(?)
	         ORDER BY `offer_id` DESC
		      LIMIT 1";
					  
	$stmt = $this->pdo->prepare($sql);
    $stmt->execute(array($sanitized));
	return $stmt->fetch(PDO::FETCH_ASSOC);		
}

In Controller class:

$cookiestring  =	urldecode($_COOKIE['shown_offer']);
$sanitized 	   = 	implode(",",array_map(intval,explode(",",$cookiestring)));	
$special_offer =    $this->page->get_offer($sanitized);

Would this be correct?

Well you can see from the coloring of that code that thereā€™s a missing " from the beginning of the SQL string, but yes, that looks correct to me.

Keep in mind that $stmt->fetch() can return FALSE if there are no matches to find.

@m_hutley Sorry I had to run out for a while.

That is true, but hat is one of the requirements in order to show an offer in the first place:

if(isset($_COOKIE['newsletter_active']) && $special_offer > 0)

Or do you think I donā€™t need the

&& $special_offer > 0

part the if statement since offers are only shown as long as they are not present in the variable $cookiestring ?

I dislike using > 0 to detect ā€œnon-falseā€, because its misleading to a future reader that $special_offer is a number rather than potentially an array. It works, I just donā€™t like it.

If you want to be completely transparent, && is_array($special_offer) would be what i would use.

You definitely do need to check that it exists, though, because the existance of the newsletter_active cookie doesnt tell you whether your database found an offer to serve or not.

2 Likes

@m_hutley. Sorry for the late response but I had some obligations yesterday evening.

Thank you for pointing me to the is_array () function. I was never really happy with the > method. Today Iā€™m gonna test the functionality and keep you posted. Thank you for all your input and pataience

@m_hutley. I just tested it and get the following error on the implode function:

Use of undefined constant intval - assumed ā€˜intvalā€™

and this is the section where this happens:

$cookiestring  			=	urldecode($_COOKIE['offers_seen']);
$sanitized 	   			= 	implode(",",array_map(intval,explode(",",$cookiestring)));

I have been Googling for this error but havenā€™t found an answer so far

Change to

implode(",",array_map('intval' ,explode(",",$cookiestring)));

intval must be a string, without quotes PHP thinks you mean a constant, but there is no constant with that name, which is why you get the error.

2 Likes

@rpkamp. Thanks a lot That indeed took the error out

Woops. Yeah, good catch Scallio. the first parameter is a string that reflects the function to be called.

@m_hutley I have a problem with initiating the special offer section.The PHP document where the handling of the special offers takes place is included in the main layout template: I set the initianal Cookie

Cookies.set('offers_seen', 0, { expires: 1000 });

for seen offers when the mailinglist form is submited

Then I have the part handling the special offers added to the main controller:

    protected function render($template, $data = array())
    {
		if (isset($_COOKIE['offers_seen'])){
			$cookiestring  			=	urldecode($_COOKIE['offers_seen']);
			$sanitized 	   			= 	implode(",", array_map('intval' , explode(",", $cookiestring)));
			$special_offer			=	$this->page->get_special_offer($sanitized);
		}		
		$site_widgets			= 	$this->widgets->get_site_widgets();						
        $layoutData = array(
		    'main_items'      	=> 	$this->page->get_main_menu(),
			'special_offer'     => 	$special_offer,			 
			'content'         	=> new View($template.'.php', $data)
        ) + $site_widgets;

        $view = new View($this->layout.'.php', array_merge($layoutData, $data));
        echo $view->render();
    }

because that way the special offers are available on the entire website. But having it like this I keep getting the following Undefined variable:notice:

Notice: Undefined variable: special_offer in ā€¦ on line 34.

Which is this line:

'special_offer'     => 	$special_offer,

While in the Console the $_COOKIE[ā€˜offers_seenā€™] is set. Not sure what I am doing wrong? Maybe you see it?

Edit: When I take the if statement out the Undefined variable:notice is not longer about special_offer but about offers_seen instead

Rightā€¦

	if (isset($_COOKIE['offers_seen'])){
			$special_offer			=	$this->page->get_special_offer($sanitized);
		}	

if this cookie is not present, then $special_offer is not set. So when you get down to defining $layoutData, thereā€™s nothing for it to read, and you get the error.
You either need a default value for special_offer, or to not include it in $layoutData if there is no offer to show. (I dont know/remember if your view is set to conditionally display special_offer or not.)

@m_hutley

Thatā€™s the funny thing. Like I said in the console(FF & Chrome) the Cookie offers_seen is there with a value 0 as to your strategie.

Where else could I include it? I thought $layoutData would be the best place since from there it is available in the entire site. What would you do in this case?

Thank you in advance

Well, PHP doesnt think so. Reload the page, and check the cookies attached to the request in the Network tab.

Youā€¦ just wouldnt? Youā€™d send layoutData without that element inside it. Again, I dont know/remember how your View is set up, whether it EXPECTS something to be there for special_offer or itā€™s set to only display IF there is something there.

I use the is_array function as you suggested

if(isset($_COOKIE['newsletter_active']) && is_array($special_offer))