myCRED Forums How-to Questions [mycred_leaderboard] based on different point type

This topic contains 12 replies, has 2 voices, and was last updated by Profile photo of oomskaap oomskaap 1 week, 5 days ago.

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • #6979
    Profile photo of oomskaap
    oomskaap
    Member

    Hi Gabriel. I have a custom leaderboard, which works great on the mycred_leaderboard shortcode.
    In my template I have the following code:
    ——just to define some custom meta to be used ———-
    <?php
    global $wpdb, $user_ID ;
    $results = get_user_meta ( $user_ID, ‘qty’, false ) ;
    $totalQty = array_sum ( $results ) ;
    $results = get_user_meta ( $user_ID, ‘grand_total’, false ) ;
    $gTotal = array_sum ( $results ) ;
    ?>

    ——-output of shortcode—————-

    <?php $html =  do_shortcode('[mycred_leaderboard wrap="" template="%user_id%" number="50"]
        <tr class="">
            <td class="col-rank"> <div class="rank">%ranking%</div></td>
            <td class="col-user">
    
                <a data-role="hovercard" data-direction="right" data-user-id="4642580" class="name
                    
                        "  "="">%display_name%
                </a>
            </td>
    
            <td class="col-owns">%user_id% </td>
    		<td class="col-img">img</td>
    
            <td class="col-points">%cred_f%</td>
        </tr>
    [/mycred_leaderboard]'); 
    $matches = array();
    preg_match_all('/<tr class="">(.*?)<\/tr>/s', $html, $matches);
    foreach($matches[1] as $output)
    {
    	preg_match_all('/<td class="col-owns">(.*?) <\/td>/s', $output, $userid);
    	$user = $userid[1][0];
    	$results1 = get_user_meta ( $user, 'qty', false ) ; 
    	$totalQty = array_sum ( $results1 ) ; 
    	$results2 = get_user_meta ( $user, 'product_name', false ) ; 
    	$products = implode("<br />", $results2 ) ;
    	$results3 = get_user_meta ( $user, 'product_id', false ) ; 
    	$img='';
    	foreach($results3 as $productid)
    	{
    		$image = wp_get_attachment_image_src( get_post_thumbnail_id( $productid ), 'single-post-thumbnail' );
    		$img .= '<a href="'.get_permalink($productid).'"><img src="'.$image[0].'" width="100px" height="100px" /></a>';
    	}
    	
    	$str = str_replace("<td class=\"col-owns\">".$user, "<td class=\"col-owns\">".$totalQty, $output);
    	$str = str_replace("<td class=\"col-img\">img", "<td class=\"col-img\">".$img, $str);
    	echo  '<tr class="">'.$str.'</tr>';
    }
    ?>

    This will give me the leaderboard based on store credits.

    Now, i want to duplicate this template, but the difference is it should display the leader board based on people who has the most REFERRAL points.

    I already know how to echo a current user’s referral points via:

    Referral points</i><b><?php echo mycred_total_per_ref( 'visitor_referring', get_current_user_id() ); ?> points

    But I am not sure how to modify the leaderboard shortcode above to be referral specific points.

    Is this possible?

    #7042

    Hey.

    This is how I would do it:

    First, I would add a new shortcode attribute called reference which then would hold the reference the leaderboard should be based on. As you correctly pointed out, the reference here is “visitor_referring”.

    So my shortcode would look like this when used:

    [mycred_leaderboard reference="visitor_referring"]
    

    Next we need to adjust the SQL Query which can do via the mycred_ranking_sql filter. It has two parameters: the query string and the attributes passed to the shortcode.

    add_filter( 'mycred_ranking_sql', 'mycred_custom_leaderboard_base', 10, 2 );
    function mycred_custom_leaderboard_base( $query, $attr = array() ) {
    	// Default
    	if ( ! isset( $attr['reference'] ) || $attr['reference'] == '' ) return $query;
    
    	extract( shortcode_atts( array(
    		'number'    => '-1',
    		'order'     => 'DESC',
    		'offset'    => 0,
    		'type'      => 'mycred_default',
    		'wrap'      => 'li',
    		'template'  => '#%position% %user_profile_link% %cred_f%',
    		'nothing'   => __( 'Leaderboard is empty.', 'mycred' ),
    		'current'   => 0,
    		'reference' => ''
    	), $attr ) );
    
    	if ( ! in_array( $order, array( 'ASC', 'DESC' ) ) )
    		$order = 'DESC';
    
    	if ( $number != '-1' )
    		$limit = 'LIMIT ' . absint( $offset ) . ',' . absint( $number );
    	else
    		$limit = '';
    
    	global $wpdb;
    
    	$mycred_log = $wpdb->prefix . 'myCRED_log';
    
    	return "SELECT DISTINCT u.ID, SUM( log.creds ) AS cred 
    			FROM {$wpdb->users} u
    			INNER JOIN {$mycred_log} log
    				ON ( u.ID = log.user_id )
    			WHERE log.ref = '{$reference}'
    			AND log.ctype = %s  
    			GROUP BY log.user_id 
    			ORDER BY SUM( log.creds ) {$order} {$limit};";
    }
    

    All other shortcodes are still usable here it’s just that we override the query with a new one.

    In 1.5 I am going to redo the leaderboard to try and make it more customizable. Preferably making it easier to create leaderboards based on different point information.

    #7626
    Profile photo of oomskaap
    oomskaap
    Member

    This works very good. Thank you!

    #7627

    This will become obsolete in 1.5 as the new leaderboard widget will allow you to create leaderbaords based on these references at will.

    #8056
    Profile photo of oomskaap
    oomskaap
    Member

    Hi Gabriel,

    I have upgraded to 1.5, and as you mentioned, our leaderboards does not work anymore.
    I’m a bit lost as to how to get it to work as it did before 1.5

    I already have your function.php code and the above template code. Which specific change do I have to do to make it work again?

    #8096

    The new Leaderboard widget allows you to base leaderboards to any reference in your log.

    If you have a look the widget, you will see that by default the “Based On” option is set to “balance”. Change this to “visitor_referring” and you get the same results as the leaderboard in this particular widget will be based on users who have gained points for referring visitors.

    I am updating the reference guide right now (the page where the link for this settings takes you).

    #8255
    Profile photo of oomskaap
    oomskaap
    Member

    Hi Gabriel, the issue is I spent a long time creating a custom leader board as on this image:

    http://i.imgur.com/vHqozgs.pnghttp://i.imgur.com/vHqozgs.png

    which is based on the code you gave me above. If i use the widget, it does work, but it just gives me an styled list: http://i.imgur.com/1e77jKM.pnghttp://i.imgur.com/1e77jKM.png

    So I do not want to use the widget on this page. Instead, i would prefer a working code as the one above. Is there no way

    [mycred_leaderboard reference="visitor_referring"]

    can work again?

    #8256

    Hey.

    So before, you used a html template for each row in your leaderboard right? You then styled these html elements to make it look the way it’s shown in the image right?

    The same html template can be used in both the widget and in the shortcode.

    Anything inside the shortcode will be used as the row template, by default, the leaderboard shortcode will render an unorganized list

    (<ul>)

    You can change this via the wrap=”” shortcode attribute by either having no wrapper or for example using wrap=”tr” if you are constructing a table.

    Example with plain no wrapper just using paragraphs:

    [mycred_leaderboard wrap=""]
    <p>#%position% - %display_name%</p>
    [/mycred_leaderboard]
    
    #11412
    Profile photo of oomskaap
    oomskaap
    Member

    Hi Gabriel,

    I have found that my list of top 50 contains a lot of entries/names like this:

    John Doe – 3000 points
    %display_name% – 3 828.00 points
    John Doe 2- 4000 points

    What does the “%display_name%” mean? That it cannot find this entry anymore in the database? user has deleted their profile?

    Is there any way to hide this entry?

    Side note: When i remove “%display_name%” from my query, the leaderboard loads very fast with rank + point total ( missing name of course), within 1 second.
    When I place it back, it takes about 20+ seconds to load. So it seems %display_name% is causing a lot of load. I am OK with that. Just wanted to bring to your attention.

    Hope to hear from you soon

    Thanks!

    #11477

    Hey.

    Thank you for bringing this to my attention. Yes these are entries of non existing users. The load time is because we load the user object for each row in the leaderboard so the bigger the leaderboard the bigger the load. This of course does not occure if you are not using any user related template tags as it is their existence that triggers the object to be loaded.

    This is also only applicable on leaderboard that are not based on balance but on a reference. When dealing with balances the leaderboard makes sure the user exists while the leaderboard based on log entries will always show all existing entries in your log.

    If you edit your point type, on the settings page under “Core Preferences” you should have a checkbox called “Delete Log entries when a user is deleted” if you prefer to keep the log clean.

    Right now the easiest way to fix this is to remove the log entries of users who no longer exists.

    #11486
    Profile photo of oomskaap
    oomskaap
    Member

    Thanks I will use that Delete entries tick-box from now on.
    Do you know how I can locate that deleted profiles?

    %display_name% – 3 828.00

    I have searched all of my database in phpMyadmin for the value 3828 and nothing comes up.

    “visitor_referring” reference does not show totals, so I cannot sort.
    I tried a few ways to track down which user has 3828 of “visitor_referring” points but I can’t find him.

    Any idea?

    Thanks!

    #11587

    Hey.

    Go to the myCRED > Log page and browse your log entries. Entries for deleted users will show in the “user” column and you can delete the entires right there.

    #11637
    Profile photo of oomskaap
    oomskaap
    Member

    My log is about 800 pages, i don’t think its worth sifting through to find the 1 by 1 point log entry and delete all each one 3828.

    I guess i’ll just live with it, untill in the future you can bulk delete total points of old deleted user accounts. One by one is too long.

    User Missing (ID: 4583) – ( i am not even sure it is this user who has the 3828 referral points )

    1.00 – Store Credits for visitor referral from: 157.55.39.166

    i tried all sql queries to find “3828” in database and it shows nothing, and points are 1 per entry and not totals so you cannot sort by total referral points highest to lower. if this was the case, perhaps I can find him because he has the most referral total points.

    Thanks for your time

Viewing 13 posts - 1 through 13 (of 13 total)

You must be logged in to reply to this topic.