Getting a list of users by sponsor

Permalink
I've added some attributes to users. Specifically, I've added "Clients" which is a number of clients that user is allowed. I've also added "Sponsor", to identify both if an account belongs to a Sponsor, and who that sponsor is.

So I try the following:

use Concrete\Core\User\UserInfo;
    $u = new User();
    $ui = UserInfo::getByID($u->getUserID());
    $clientcount = $ui->getAttribute('Clients');
    $list = new \Concrete\Core\User\UserList();
    $list->filterByAttribute('Sponsor',$ui->getUserName(),'=');
    $list->sortByUserName();
    $clientlist = $list->get();


This gives me an error stating:

An exception occurred while executing 'SELECT u.uID FROM Users u LEFT JOIN UserSearchIndexAttributes ua ON u.uID = ua.uID WHERE (ak_Sponsor = ?) AND (u.uIsActive = ?) AND (u.uIsValidated != 0) GROUP BY u.uID, u.uName ORDER BY u.uName asc' with params ["GeeEM", true]: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ak_Sponsor' in 'where clause'

What am i missing?

GeeEM
 
mnakalay replied on at Permalink Reply
mnakalay
Usually attribute handles are all lower case. Are you sure it's "Sposor" and not "sponsor" ?
mnakalay replied on at Permalink Reply
mnakalay
Also to simplify your code, instead of
$u = new User();
$ui = UserInfo::getByID($u->getUserID());

you can do
$u = new User();
$ui = $u->getUserInfoObject();
GeeEM replied on at Permalink Reply
GeeEM
I have checked the capitalization, but I get the same error (with sponsor capitalized).
GeeEM replied on at Permalink Reply
GeeEM
When I simplify the code, the error swaps to:

Exception Occurred: /public_html/packages/phpcodeblock/blocks/phpcodeblock/view.php(20) : eval()'d code:7 Call to a member function getAttribute() on string (0)
GeeEM replied on at Permalink Reply
GeeEM
Is it possible that UserList doesn't have custom attributes exposed to it, so i need to use something else as it's a custom attribute?
GeeEM replied on at Permalink Reply
GeeEM
So I made some test changes. Now my code reads:

use Concrete\Core\User\UserInfo;
    $u = new User();
    $ui = UserInfo::getByID($u->getUserID());
    $clientcount = $ui->getAttribute('Clients');
    use Concrete\Core\User\UserList;
    $list = new UserList();
    //$list->filterByAttribute('sponsor',$ui->getUserName(),'=');
    $list->sortByUserName();
    $clientlist = $list->get();
    echo 'List:';
    if(!empty($clientlist)) {
        echo '<br/><ul>';
        foreach ($clientlist as &$item) {
            echo '<li>'.$item.'</li>';
        }


With the result being...

UserInfo: 23
UserInfo: 18
UserInfo: 33
UserInfo: 32
UserInfo: 15
UserInfo: 3
UserInfo: 14
UserInfo: 19
UserInfo: 29
UserInfo: 16
UserInfo: 12
UserInfo: 21
UserInfo: 31
UserInfo: 35
UserInfo: 2
UserInfo: 30
UserInfo: 34
UserInfo: 22
UserInfo: 26
UserInfo: 24
UserInfo: 28
UserInfo: 20
UserInfo: 13
UserInfo: 27
UserInfo: 25
UserInfo: 1

So it looks like I'm only getting the user id. How do i pull the "sponsor" field?
mnakalay replied on at Permalink Reply
mnakalay
instead of $list->get() try $list->getResults() to get user objects
GeeEM replied on at Permalink Reply
GeeEM
I get the same result. When I un-comment the line which causes the error, I get the same Unknown columns error.
ConcreteOwl replied on at Permalink Reply
ConcreteOwl
You have &$item did you mean it to be $item
GeeEM replied on at Permalink Reply
GeeEM
Both have the same effect. Using &$item simply uses references to the data, rather than the data itself.
LucaBn replied on at Permalink Reply
LucaBn
I'm not sure it will solve the problem but you can check if the attributes have "Field available in advanced search" flagged. If it's not, try to flag it.
GeeEM replied on at Permalink Reply
GeeEM
Tried this just now. Same result. It only seems to be exposing the ID's.
GeeEM replied on at Permalink Reply
GeeEM
If i just want to pull a list of users with text in a custom field, how would I do that? Is UserList the correct approach?
ConcreteOwl replied on at Permalink Reply
ConcreteOwl
This is completely untested, but what happens if you do this...
<?php
Loader::model('user_list');
$ul = new UserList();
//returns a list of users
$users = $ul->get();
$select_users_options = array();
//create an array
foreach($users as $user) {
  $select_user[$user->getUserID()] = $user->getUserName();  
  echo $user->getUserName();  
  $select_user[$user->getUserID()] = $user->getUserClients();  
  echo $user->getUserClients();  echo ", ";
  $select_user[$user->getUserID()] = $user->getUserSponsor();  
  echo $user->getUserSponsor();  
  }
GeeEM replied on at Permalink Reply
GeeEM
This is working. I assume getUserSponsor is one of those "Magic functions" I have heard mentioned. While I can make this work, I would prefer to filter the data I am sending back, to cut down on processing at the PHP level. Do you know if this is possible?
mnakalay replied on at Permalink Reply
mnakalay
So I investigated and the answer is actually silly.

Your code is correct. The problem comes from this line
echo '<li>' . $item . '</li>';

You see $item is an instance of UserInfo as it should be but when you concatenate it to a string you are effectively telling PHP you want to turn it into a string.

In that situation PHP has 2 options: either there is a function to convert that particular object to a string and PHP will use it or it will throw an error.

Now if you look at the class UserInfo you will find this
public function __toString()
    {
        return 'UserInfo: ' . $this->getUserID();
    }

Which is why you are getting that list of IDs. So For instance just do
$item->getUserName();

And you'll see that you do have an object.
GeeEM replied on at Permalink Reply
GeeEM
Thank you. This explains somewhat the issue I've been seeing. In testing, I am able to pull back user names. Is there a way to apply the filter, as filterByAttribute seems not to work? Or do I just need to loop all users each time and check the data line by line?
mnakalay replied on at Permalink Reply
mnakalay
I tried to filter by attribute the same way you did and it works.
Make sure you're using the attribute's handle and not its name.
mnakalay replied on at Permalink Best Answer Reply
mnakalay
To be more precise I used all the modifications I mentioned in this post and it worked flawlessly without any error or problem
$u = new User();
$ui = $u->getUserInfoObject();
$list = new UserList();
$list->filterByAttribute('sponsor', $ui->getUserName(), '=');
$list->sortByUserName();
$clientlist = $list->getResults();

I used the function getUserInfoObject() which worked and I used getResults() instead of get() because get() is deprecated.
GeeEM replied on at Permalink Reply
GeeEM
I moved the order around a bit and re-tested. Same error.

Then, I had the idea to copy the text from the Attributes UI and paste it in the code. This worked. I don't know if there was some strange invisible character in there or something, but it immediately worked!

Sorry to have been such a pain, but it was hurting my brain!
mnakalay replied on at Permalink Reply
mnakalay
Don't worry about it, I'm always happy to help and we all learned something so it's all good :)

Good job on figuring out that last bit.