0

I have the following code:-

<?php 

if(!is_user_logged_in()) {
    $fav_cookie = array($_GET['job_fav']);
    $cookie_url = '/jobs/?job_fav=<?php the_ID(); ?>';

    if($job_fav !='') {
         setcookie(COOKIE_PREFIX . "job_fav",    " ", time() - 3600);
         setcookie(COOKIE_PREFIX . "job_fav", array($fav_cookie));
         header("Location: $cookie_url");
    }
?>

<a href="/jobs/?job_fav=<?php the_ID(); ?>">
    <div class="job-single-favourite icon-<?php echo $job_sector_html; ?>
        <?php if (in_array(get_the_ID(), $fav_cookie)) {
                  echo ' starred-job';
              }
        ?>">
    </div>
</a><!-- none-logged-in starred-job -->

<?php } ?>

This is working fine, but it is only storing one value as a cookie at a time.

Basically what I am wanting to do is on click of the favourite icon it needs to store the job ID within the $fav_cookie array.

What is happening at the moment is that if you favourite a job $fav_cookie is being replaced by the new job ID. I somehow want to add each cookie inside the $fav_cookie array so it would become 113, 120, 234 for example, instead of replacing the ID each time.

If I haven't explained what I am wanting to achieve in great enough detail, let me know and I will amend my post.

EDIT:--

Just to add, the following works:-

$jobID = get_the_ID();
$jobListing = array(get_the_ID());
$html = '';
//$currentIDs = explode('|', $_COOKIE[COOKIE_PREFIX . 'job_fav']);
$currentIDs = array('493','311');

var_dump($currentIDs);
foreach ($jobListing as $job) {

    $customClass = (in_array($jobID, $currentIDs)) ? ' starred-job' : '';

   // $html = '';
    $html .= '<a href="/jobs/?job_fav=' . htmlspecialchars($jobID) . '">';
    $html .= '<div class="job-single-favourite icon-' . htmlspecialchars($job_sector_html) . $customClass . '">';
    $html .= '</div></a>';
}


echo $html;

All I need now is $currentIDs to display be an array of the favourite jobs defined from $_COOKIE and it should be done.

$currentIDs = explode('|', $_COOKIE[COOKIE_PREFIX . 'job_fav']); is an empty array

EDIT 2

Okay I now have the following:-

$jobID = get_the_ID();
$jobListing = array(get_the_ID());

$favourite_cookie = array($_GET['job_fav']);
$ids_string = implode('|', $favourite_cookie);
setcookie('job_fav', $ids_string);

var_dump($_COOKIE['job_fav']);


$ids_string = $_COOKIE['job_fav'];
$ids = explode('|', $_COOKIE['job_fav']);
<?php 
if (!is_user_logged_in()) {

$jobID = get_the_ID();
$jobListing = array(get_the_ID());
$html = '';
$currentIDs = explode('|', $_COOKIE[COOKIE_PREFIX . 'job_fav']);
$currentIDs = $ids;

foreach ($jobListing as $job) {

    $customClass = (in_array($jobID, $currentIDs)) ? ' starred-job' : '';

    $html = '';
    $html .= '<a href="/jobs/?job_fav=' . htmlspecialchars($jobID) . '">';
    $html .= '<div class="job-single-favourite icon-' . htmlspecialchars($job_sector_html) . $customClass . '">';
    $html .= '</div></a>';
}


echo $html;

} ?>

And now have two issues:-

  • When I favourite a job, I have to click twice in order for it to update.
  • $_COOKIE['job_fav'] gets replaced with the new job ID every time you favourite a different job, instead of adding it to the array
7
  • So you don't want to set several cookie (as title states) but update a previous one? Commented Feb 9, 2016 at 17:05
  • That is correct @ÁlvaroGonzález - sorry the title was misleading Commented Feb 9, 2016 at 17:12
  • $cookie_url is bad. you cannot embed php code blocks inside other php code blocks...you're passing the literal characters <, ?, p, etc... as the job_fav query value. and your'e setting the SAME cookie name, so the new value replaces the previous one. cookies also cannot store arrays. they're just a text string. you'd have to encode/serialize your array, save/retrieve it from the cookie, decode/unserialize, mod it, recode, then re-save Commented Feb 9, 2016 at 17:12
  • Maybe put data into an array and use serialize() and unserialize()? Commented Feb 9, 2016 at 17:13
  • See also stackoverflow.com/questions/8690537/… Commented Feb 9, 2016 at 17:22

2 Answers 2

1
+50

You could use implode and explode when creating/retrieving the $_COOKIE.

So for example when you want to create/update the list of IDs within the $_COOKIE you would first explode the current $_COOKIE if set.

if (isset($_COOKIE[COOKIE_PREFIX . 'job_fav'])) {
    $jobIDs   = explode('|', $_COOKIE[COOKIE_PREFIX . 'job_fav']);
    $jobIDs[] = $_GET['job_fav']; // Add new ID to the list.

    // We store them as a string, that we can explode when needed.
    setcookie(COOKIE_PREFIX . "job_fav", implode('|', $jobIDs)); 
}

If you ever want to turn the $_COOKIE into the array format, you just do:

explode('|', $_COOKIE['job_fav']);

I believe that you give you a good idea of how you can store it. Any questions, just let me know.

Edit: I had a few spare minutes, I tried to implement it/clean up your code a little. Not sure if I got it all right but it's at least something for you to work off:

if (!is_user_logged_in()) {

    $id          = the_ID();
    $favouriteID = $_GET['job_fav'];
    $cookieURL   = '/jobs/?job_fav=' . $id;

    $currentIDs  = []; // Storage Array.

    // If the user has the $_COOKIE set already.
    if (isset($_COOKIE[COOKIE_PREFIX . 'job_fav'])) {
        $currentIDs = explode('|', $_COOKIE[COOKIE_PREFIX . 'job_fav']);

        // Append the new ID.
        $currentIDs[] = $favouriteID;
        setcookie(COOKIE_PREFIX . 'job_fav', implode('|', $currentIDs));
        header('Location: ' . $cookieURL);
        exit;
    }

    $currentIDs[] = $favouriteID;
    setcookie(COOKIE_PREFIX . 'job_fav', implode('|', $currentIDs));

    // Build up the HTML.
    $html  = '';
    $html .= '<a href="/jobs/?job_fav=' . htmlspecialchars($id) . '">';
    $html .= '<div class="job-single-favourite icon-' . htmlspecialchars($job_sector_html);
    if (in_array($id, $currentIDs)) {
        $html .= ' starred-job';
    }
    $html .= '">';
    $html .= '</div></a>';

    echo $html;
}

Can see it here: https://ideone.com/ivxRAT

There are multiple other ways to clean up the above, but without knowing your code base and what the get_ID() and get_the_ID() functions are doing it's hard for me to do it. Really if these are just returning the same ID for each instance each time, you may as well call it once at the top, store it in a variable and use that when query whether the ID exists in the array, etc.

Edit2: No idea why your code isn't working, the logic works fine for me, it will now store multiple $_COOKIES as shown in the ideone.

So I can only presume that your problem is how you're then using your $_COOKIE to decide whether you need to apply the styles or not.

So since I have no idea about how you are doing this, I can only guess.

I'm guessing somewhere you have a database query that pulls out all your current jobs. I'm also guessing that you loop through that data to print them out to the page. So here is what I would suggest:

$jobListing = <PULLDATAFROMDATABASE>

$html = '';
$currentIDs = explode('|', $_COOKIE[COOKIE_PREFIX . 'job_fav']);
foreach ($jobListing as $job) {

    $customClass = (in_array($job->id, $currentIDs)) ? ' starred-job' : '';

    $html .= '<a href="/jobs/?job_fav=' . htmlspecialchars($id) . '">';
    $html .= '<div class="job-single-favourite icon-' . htmlspecialchars($job_sector_html) . $customClass . '">';
    $html .= '</div></a>';
}

echo $html

Edit3:

How to set the cookies:

$ids = array(1,2,3,4);
$ids_string = implode('|', $ids);
setcookie('job_fav', $ids_string);

How to get the cookies:

$ids_string = $_COOKIE['job_fav'];
$ids = explode('|', $_COOKIE['job_fav']);

So if we do: print_r($ids);

We get:

Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )

Edit3:

The first part.

$jobID        = get_the_ID();
$jobListing   = array(get_the_ID());
$favouriteIDs = array();

$favourite_cookie = $_GET['job_fav']; // This is the new id we want to add to the array?
if (isset($_COOKIE['job_fav'])) {
    $favouriteIDs = explode('|', $_COOKIE['job_fav']);
}
$favouriteIDs[] = $_GET['job_fav']; // Append the new ID onto the array.
setcookie('job_fav', implode('|', $favouriteIDs));

var_dump($_COOKIE['job_fav']);

The other part

if (!is_user_logged_in()) {

    $jobID        = get_the_ID();
    $jobListing   = array(get_the_ID());
    $html         = '';
    $favouriteIDs = explode('|', $_COOKIE['job_fav']);

    foreach ($jobListing as $job) {

        $customClass = (in_array($jobID, $favouriteIDs)) ? ' starred-job' : '';

        $html = '';
        $html .= '<a href="/jobs/?job_fav=' . htmlspecialchars($jobID) . '">';
        $html .= '<div class="job-single-favourite icon-' . htmlspecialchars($job_sector_html) . $customClass . '">';
        $html .= '</div></a>';
    }

    echo $html;
}

Don't know if there's something strange going on in your code, but you randomly added Opening/Closing PHP tags. If they need to be there for some reason and this isn't the full code following on from one another, you can add them back in.

Sign up to request clarification or add additional context in comments.

16 Comments

Thanks @Virtual Pigeon - Although when I var_dump($html); I get a result like '311311string(78)' ?
@nsilva Can you clarify what the the_id() and get_the_id() functions do, and what they return for me please?
get_the_id() and the_id() are both the same, they both get the unique ID of the job, e.g. job id = '130'. If it helps, here is the link to the job listings which has the 'favourite' function on there (which on the site, you can only favourite one job at the time as this is the original code): distinctrecruitment.com/jobs
@nsilva I've made some edits, it seems to be working for me, although I had to fake the methods and the $job_sector_html bit which I presume you have defined elsewhere because it isn't defined in your example. All the same though, the concept you need is to explode() and implode() the array to strings and back when storing inside a cookie.
@nsilva You could 'fake' the favourite initially, so have some JQuery that adds/removes the style on click of a star. That way the stars will appeared as the end user would expect. The other way would probably be to use AJAX although i'm not 100% sure how you would implement that cleanly without a fairly large re-write of how you handle favourites.
|
0

Edit: your original example wouldn't work. setcookie expects a string as the value, you need to serialize the data. Answer updated.

You need to get the current value of the cookie and append the new value to the array. Try something like this.

$cookies = array();
if (!empty($_COOKIE[COOKIE_PREFIX . "job_fav"])) {
  $cookies = $_COOKIE[COOKIE_PREFIX . "job_fav"];
  $cookies = unserialize($cookies);
}
$cookies[] = $fav_cookie;
setcookie(COOKIE_PREFIX . "job_fav", serialize($cookies));

Then when you need the cookie values:

$job_favs = unserialize($_COOKIE[COOKIE_PREFIX . "job_fav"]);

4 Comments

Just tried and it is still only saving 1 favourite at a time
Sorry, I had a typo (extra 's'). Try again. OP said that their example was working using an array in set_cookie. All I'm suggesting is adding the new value to the current value. The current cookie value would be available in the super global $_COOKIE.
Thanks @ChanceG although it doesn't seem to be working still, still doing one job at a time, and if I navigate to /jobs/ without a job_fav, no values are 'favourited'
Thanks again @ChanceG - I don't understand why $job_favs returns bool(false) with the updated code though

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.