Ok so we have things, and we want to favourite/unfavourite them as done. First, we need 2 functions:
saeed_is_favourited( int $post_id, string $thing_to_favourite )
( where$thing_to_favourite
is the thing we’re marking as saved/favourited/etc, and$default
is the value to return if we don’t know yetsaeed_set_favourited( int $post_id, string $thing_to_favourite, bool $favourited )
where we set$thing_to_favourite
on that post as favourited or not favourited
Then you will need a way to send an AJAX request to call saeed_set_favourited
with the requested value.
We will store if it’s favourited in user meta using a user meta with a key like this:
saeed_favourite_123_ABC
Where 123
is the post ID, and ABC
is the thing we’re favouriting/not favouriting. This thing is a string, any string of your choosing. In the examples I give, it is completely arbitrary. It is not the slug of a post or a meta key, or a username. I could use those if I wanted, or I could make them up.
Here is an attempt at implementing saeed_is_favourited
function saeed_is_favourited( int $post_id, string $thing_to_favourite ) : bool {
$user_id = get_current_user_id();
$meta_key = 'saeed_favourited_' . $post_id . '_' . $thing_to_favourite;
$result = get_user_meta( $user_id, $meta_key, true );
return boolval( $result );
}
Used like this:
if ( saeed_is_favourited( get_the_ID(), 'apples' ) ) {
echo "you have favourited apples on this post";
} else {
echo "you have not favourited apples on this post";
}
Here is an attempt at implementing saeed_set_favourited
function saeed_set_favourited( int $post_id, string $thing_to_favourite, bool $favourited ) : void {
$user_id = get_current_user_id();
$meta_key = 'saeed_favourited_' . $post_id . '_' . $thing_to_favourite;
update_user_meta( $user_id, $meta_key, $favourited );
}
Notice that I used update_user_meta
, not add_user_meta
. add_user_meta
can create multiple meta key/value pairs, meta keys are not unique.
Finally, we need a way to set if it has been favourited or not. Here is an old style Admin AJAX handler:
function saeed_ajax_favourite_a_thing() : void {
$post_id = 0;
if ( ! empty( $_POST['post_id'] ) {
$post_id = intval( $_POST['post_id'] );
} else {
wp_die( 'a post_id number is needed, none was provided' );
}
$thing_to_favourite="";
if ( ! empty( $_POST['thing_to_favourite'] ) {
$thing_to_favourite = $_POST['thing_to_favourite'];
} else {
wp_die( 'a thing_to_favourite is needed, none was provided' );
}
$favourite = false;
if ( ! empty( $_POST['favourite'] ) {
$favourite = boolval( $_POST['favourite'] );
} else {
wp_die( 'a favourite is needed, either true or false, none was provided' );
}
saeed_set_favourited( $post_id, $thing_to_favourite, $favourite );
}
add_action( 'wp_ajax_saeed_ajax_favourite_a_thing', 'saeed_ajax_favourite_a_thing' );
You would then pass a post ID, a thing_to_favourite representing the thing you want to favourite, and a true/false for wether it is to be favourited or unfavourited.
E.g. this would favourite apple
:
$.ajax({
type: 'POST',
url: ajax_object.ajaxurl,
data: {
action: 'saeed_ajax_favourite_a_thing',
post_id: post_id
thing_to_favourite: 'apple',
favourite: true
}
});
You should consider looking into the more modern REST API endpoints as a cleaner replacement for this AJAX handler.
You can also use saeed_is_favourited
to construct your frontend, and the AJAX to toggle the items on/off.
Because it used user meta, the favouriting will work on a per user basis.
You will want to check is_user_logged_in()
as this code will not work for logged out users.
Note that none of this code is tested, you may need to make modifications after integrating it into your code