I'm trying to display user list using Views, ordered by user points, limited to one Userpoints category.

I'm using {users} as base table. Views is filtered by "Userpoints: Points category" for specific Userpoints category. Using this filter, the {users} table joined to {userpoints} table. Here is the generated SQL :

SELECT users.uid AS uid, users.name AS users_name, userpoints.points AS userpoints_points, 'user' AS field_data_field_profile_picture_user_entity_type, 'user' AS field_data_field_profile_full_name_user_entity_type, 'user' AS field_data_field_profile_interests_user_entity_type
FROM 
{users} users
LEFT JOIN {userpoints} userpoints ON users.uid = userpoints.uid
WHERE (users.status <> '0')AND(userpoints.tid IN  ('20', '21', '22'))
ORDER BY userpoints_points DESC

Users who already have points in the category are displayed on the list. But, users who have no point yet are not displayed. In SQL result, these users are not displayed because having NULL values for {userpoints}.tid field, but the result filtered to '20', '21', and '22'.

I added 'allow empty' definition to filter handler in userpoints_views_handler_filter_category.inc file in order to allow Views including NULL value.

<?php
/**
 * Filter by category
 */
class userpoints_views_handler_filter_category extends views_handler_filter_in_operator {
  function construct() {
    parent::construct();
    $this->definition['allow empty'] = TRUE;
  }
  
  
  function get_value_options() {
    if (!isset($this->value_options)) {
      $this->value_title = t('Category');
      $this->value_options = userpoints_get_categories();
    }
  }
}

It adds EMPTY operator to the filter. And, user who have no points yet are now included on the list.

Or, is it another way to get user list, ordered by points, for specific category?

Comments

berdir’s picture

How does the resulting query look with that option set? And can you provide your change as a patch?

gantenx’s picture

The resulting query looks like

SELECT users.uid AS uid, users.name AS users_name, userpoints.points AS userpoints_points, 'user' AS field_data_field_profile_picture_user_entity_type, 'user' AS field_data_field_profile_full_name_user_entity_type, 'user' AS field_data_field_profile_interests_user_entity_type
FROM 
{users} users
LEFT JOIN {userpoints} userpoints ON users.uid = userpoints.uid
WHERE ( (users.status <> '0') )AND( (userpoints.tid IN  ('20', '21', '22')) OR userpoints.tid IS NULL )
ORDER BY userpoints_points DESC

I attach the patch.

berdir’s picture

Version: 7.x-1.0 » 7.x-1.x-dev
Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, userpoints_views_handler_filter_category.inc_.patch, failed testing.

berdir’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, userpoints_views_handler_filter_category.inc_.patch, failed testing.

gantenx’s picture

Version: 7.x-1.x-dev » 7.x-1.0
Status: Needs work » Needs review
StatusFileSize
new726 bytes

It looks like I attached -p0 patch. Just read out how to create patch. Hope this is correct. :)

gantenx’s picture

Component: Code: userpoints_views » User interface

Hi Berdir,

Is this patch going to be applied to userpoints_view?

berdir’s picture

Yes, that's the plan, although it will take a few weeks before I can test it myself (which I want to do before commiting it).

phantom21’s picture

This solution can be implemented using the Views UI, so I wonder whether a patch is really required.

Interestingly, I was struggling with the same issue and came across gantenx's patch. I implemented the query in #2 using the views UI and it worked. Essentially, you create an OR filter group in the Filter criteria, where you can specify "Points Category is empty" as one of the filters.

The beauty of this solution is that people who want to shows users with 0 points can do within Views and those who don't want to show users with 0 points can continue to do so.

Gantenx, thank you for your idea.

gantenx’s picture

Yap, "allow empty" filter makes this module more flexible.

Thanks, phantom21, you wrote what was on my mind much clearer and more generalized than I did.

berdir’s picture

Category: feature » support
Status: Needs review » Fixed

Yes, but what phantom21 meant is that your patch is not necessary to get the desired result.

You simply add two conditions on points category once with is empty and another one with the specific category you want. Then you can go the and/or screen, add a new group, choose type or and add both conditions to that group.

I've justed tested that and it works perfectly fine, without your patch.

The only issue is that when you also show the category, it will show "General" for the users with 0 points but it is not possible to fix that.

Changing this to a support request and marking it as fixed.

gantenx’s picture

I just tried user points without my patch. And it worked. The empty condition is now there. It wasn't there before. It looks like I've been misconfigured. Sorry, entirely my fault.

phantom21’s picture

Category: support » bug
Priority: Normal » Major
Status: Fixed » Active

i just found out that the solution in #10 and #12 will not work in all cases. If you have multiple categories and a user happens to have some points in any category other than the one that you want to display in your view, then that user will not be shown.

For example, in my case, users earn points in two categories. I have a view to display all users ranked by points in category 1. The solution in #10 and #12 works fine as long a user has points in category 1 or does not have any points in any category. However if a user does not have any points in category 1, but has points in category 2, then that user does not get shown in the view created using the above solution.

One solution could be to be able to add a filter that checks whether any specific points category is empty. I could not figure out how to do that in the view UI in the current version of User Points.

Any pointers? Thanks.