Skip Navigation

[Resolved] Favorite Posts By Logged In User (Add To / Remove not working properly)

This thread is resolved. Here is a description of the problem and solution.

Problem: I would like Users to be able to choose certain posts as favorites. They should also be able to remove them from favorites.

Solution:
Create a repeating numeric field on your post type called "favorites". This field will be updated to add the current User's ID when they select a favorite. When they unfavorite a post, this field will be updated to remove their ID.

Create a CRED form that allows you to modify the posts that can be favorited. Remove all the content from the CRED form and replace it with the following code:

[credform class='cred-form cred-keep-original']
 
   [wpv-conditional if="( [toolset_is_favorite id='[wpv-post-id]'] eq '1' )"]
        [cred_generic_field field='remove-favorite' type='hidden' class='']
         {
           "required":0,
           "validate_format":0,
           "default":"1"
          }
        [/cred_generic_field]
      [/wpv-conditional]
       
    [cred_field field='form_submit' value='Favorite' urlparam='' class='x-btn x-btn-global mam']
[/credform]

Add the following JavaScript to your CRED form's JS panel:

jQuery(window).bind("load", function() {
   jQuery( "form[id^='cred_form_368']").find("input[type='submit']").val(jQuery( "input[name='remove-favorite']").length ? "Remove from Favorites" : "Add to Favorites");
   }
)

This code will toggle between showing "Add to Favorites" and "Remove from Favorites" as the button name.

Add the following PHP to your child theme's functions.php file:

add_action('cred_save_data_368', 'sda_user_favorites',10,2);
function sda_user_favorites($post_id, $form_data) {
    if( isset($_REQUEST['remove-favorite']) ) {
        delete_post_meta($post_id, 'wpcf-favorites', get_current_user_id());
    } else {
        add_post_meta($post_id, 'wpcf-favorites', get_current_user_id(), false);
    }
}
 
/* Favorites shotcode for use as a conditional */
add_shortcode( 'toolset_is_favorite', 'toolset_is_favorite_func');
function toolset_is_favorite_func($atts)
{
  global $wpdb;
  $post_id = $atts['id'];
  $user_id = get_current_user_id();
  $favorites = $wpdb->get_results( "SELECT * FROM wp_postmeta WHERE meta_key = 'wpcf-favorites' AND post_id = $post_id AND meta_value = $user_id LIMIT 1");
  return sizeof($favorites) ? 1 : 0;
}

Be sure to add the toolset_is_favorite shortcode in Toolset > Settings > Frontend content > 3rd party shortcode arguments.

Place the CRED form in a View of posts, or in a Content Template for these posts.

Relevant Documentation: https://toolset.com/documentation/programmer-reference/cred-api/#cred_save_data
https://toolset.com/documentation/user-guides/conditional-html-output-in-views/

This support ticket is created 6 years, 11 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 18 replies, has 3 voices.

Last updated by Team DNK 6 years, 11 months ago.

Assisted by: Christian Cox.

Author
Posts
#600337

should I consider your new BETA Types and Views Post Relationship approach instead of using a repeating field?
That's a great question. The new betas don't allow you to relate posts to Users in any new meaningful ways. They allow you to create more meaningful relationships between and among post types. So assuming you are not using some other custom post type to represent Users, you would probably still need to use custom fields to store references between your CPT posts and Users. Also you should be aware that CRED is not currently integrated with these new beta features yet. Furthermore, there's no timeline available for when these features will be released as stable versions. I encourage you to try out the betas and see what's possible, but I don't think they will be helpful in this particular case.

#600896

Hi Christian... I am testing the new beta Toolset Relationships and super pleased with this development direction. I have read elsewhere that the relationship functionality does not relate posts to users and understand that limitation. My concerns have to do with efficiency on a site with 10,000 or more Users, Favoriting upwards of 50 post each.

1. What I was getting at in my previous post was, would it be more efficient to create a post type to be used to store the user ID like you are doing with the repeating field? The idea here would be that instead of the Favoriting functionality looking for the users ID in the posts repeating field, it would be checking to see if any child posts with the Users ID exist for the post.

2. If the best method is as we have done earlier in this thread, using a repeating field in the post type itself, could you recommend a way to make the editor more manageable such as hiding that particular field from the editor or some other method as there will be other custom fields that I do want visible in the WordPress editor.

3. Further, when using the repeating field in the post method as outlined, are there any adverse efficiency hits on the server or is this a normal and efficient approach that I can feel comfortable deploying on a site of the size mentioned here?

Kind Regards,
Dave

#600912

1. What I was getting at in my previous post was, would it be more efficient to create a post type to be used to store the user ID like you are doing with the repeating field? The idea here would be that instead of the Favoriting functionality looking for the users ID in the posts repeating field, it would be checking to see if any child posts with the Users ID exist for the post.
Creating another post type to store the favorite ID introduces an additional level of complexity in filtering and displaying information, more database queries to access the same information, and more database records to search through when performing queries. So no, it would not be more efficient.

2. If the best method is as we have done earlier in this thread, using a repeating field in the post type itself, could you recommend a way to make the editor more manageable such as hiding that particular field from the editor or some other method as there will be other custom fields that I do want visible in the WordPress editor.
If you put this custom field in its own field group, you can toggle the entire field group panel on or off in the admin area by clicking the top of the panel. If you never want it to display, click the Screen Options tab in the top right corner of the post editor screen and you can uncheck any field group.

3. Further, when using the repeating field in the post method as outlined, are there any adverse efficiency hits on the server or is this a normal and efficient approach that I can feel comfortable deploying on a site of the size mentioned here?
To determine whether or not post ABC is a Favorite of User Joe Smith, it's no more or less performant than any other postmeta table query where multiple values for a custom field are stored as separate entries. It's one query on one table, and WP already has the required query parameters - you will supply the Postmeta Key, and User ID and Post ID are already known by WP.

As you add Users and add Favorites, database queries will inevitably slow down simply because of the number of records - this is unavoidable in any system. Caching is the best way to improve that performance, and there are several 3rd-party caching plugins available that you could investigate and implement.

#600958

Many Thanks Christian... Your support regarding this matter is so appreciated. Being able to bake this functionality into my site in a total Toolset manner is fantastic, again thank you.

Kind Regards,
Dave