Jump to content

How to find usernames by userid array, return as key value array


modifiedcontent
 Share

Recommended Posts

I am trying to integrate another script, Questions2Answer, with Processwire user management. The script needs an array with key/value pairs for user->name => user->id 

The script provides an array $userids with active user->ids that looks like this var_dumped for a page with two users:

array(2) {
  [0]=>
  int(1107)
  [1]=>
  int(41)
}

How can I take $userids, find the corresponding $user->names in Processwire as values and then return that to Q2A as a clean key/value array?

This is probably basic PHP, but I have tried so many variations that I now completely lost the plot. Any pointers appreciated.

 

Link to comment
Share on other sites

This is untested, but you can use something along the lines of this

<?php
$userIds = [1, 2, 3]; // list of ids

// build a selector like id=1|2|3|4
$userList = users()->find("id=" . join('|', $userIds));

$names = $userList->getProperty('name');
$ids = $userList->getProperty('id');

// create an array of [username => userid]
$namesToIds = array_combine($names, $ids);

// or use array reduce
// you need basic PHP arrays, which you can get with WireArray::getArray() method
$namesToIds = array_reduce($userList->getArray(), function ($carry, $user) {
    // perform some other checks
    // ...

    $carry[$user->name] = $user->id; // fill array with name => id pairs
    return $carry;
}, []); // start with an empty array

 

  • Like 2
Link to comment
Share on other sites

Thank you abdus !

I had come across array_combine, but had no idea how to use it. I have now tried something like this:

function qa_get_public_from_userids($userids) {

global $users;
	
// build a selector like id=1|2|3|4
$userlist = $users->find('id=' . join('|', $userids));

$names = $userlist->getProperty('fullname');

// create an array of [username => userid]
$useridtopublic = array_combine($userids, $names);

return $useridtopublic;
}

That still doesn't work; $userlist is not an array, but a "piped string" (?) of user ids. Same as $userids, but another format.

Can $users->find be used with multiple selectors? Or did you really mean to use 'users()->find'? users()->find produced server errors for me.

The $names line should probably be a foreach loop?

How do you get a key/value array out of a foreach loop? That is one of my main questions that I keep running into.

Will try again tomorrow...

Link to comment
Share on other sites

When building selectors, you can combine multiple values by OR (pipe | character). This is a way to say "find me users with id 1 or 2 or 3 ...", and PW should return every user whose id is in that list.

Since "id=1|2|3" itself is a selector, yes, you can combine it with other terms as well.

array_combine takes in two parameters, first one is for keys, second is values, and creates a new array from those keys and values. So I used it with usernames as keys and ids as values to get [username => userid] type of array. But you can achieve the same result with plain foreach loop as well.

Using your sample code you'd use

<?php
function qa_get_public_from_userids($userids) {
	// userids is an array of integer ids [13, 456, 74] etc
    
    // global $users;
    // you can use wire() function instead of globals to access PW variables inside functions
    $userlist = wire()->users->find('id=' . join('|', $userids));


    // usernames are stored in 'name' property
    // Unless you need [fullname => id] array, you should use 'name'

    // create an array of [username => userid]
    $nameWithId = [];

    foreach ($userlist as $u) {
        $nameWithId[$u->name] = $u->id;
    }

    return $nameWithId;
}

Also the reason you're getting errors from users() function is they're a part of Functions API, which is disabled under a switch.

 

 

  • Like 2
Link to comment
Share on other sites

I keep getting 'PHP Fatal error:  Call to undefined function wire() ...', with or without '$config->useFunctionsAPI = true;' in the config.php

This version had no error, but returns an empty (0/null) array:

Spoiler

function qa_get_public_from_userids($userids) {

global $users;

// build a selector like id=1|2|3|4
$userlist = $users->find('id=' . join('|', $userids));

$useridtopublic = [];

foreach ($userlist as $u) {
        $u->id = $useridtopublic[$u->fullname];
    }

return $useridtopublic;
}

 

I have been trying variations of this for the last two days, going in circles.

I have a custom field 'fullname', so ignore that, could be 'name' instead.

Will try again later...

I'd like to try array_combine or something like that. I'd need two valid arrays. var_dump($userids) returns a healthy looking array. Getting that second array of fullnames is my problem. Or would it work if I can get wire() to work?

$userlist is not an array, so that foreach can never work?

Link to comment
Share on other sites

10 minutes ago, modifiedcontent said:

Call to undefined function wire()

Do you have namespace

<?php namespace ProcessWire;

declared on top of your files?

 

What shows up when you var_dump($userlist) inside the function?

  • Like 1
Link to comment
Share on other sites

$userlist is not an array - at least my version via $users-> and global. var_dump($userlist) produces a server error. echo $userlist displays a piped string of ids.

I can't get wire() to work in the external script.

In which file should I add 'namespace ProcessWire'? The function is in another script that bootstraps PW by including the index. Shouldn't that be enough?

The var_dump(wire()->users->find('id>0')) results do not look like anything my script could use. Is there no simple way to convert a piped string into an array?

Link to comment
Share on other sites

You should see the details of the error when you're logged in. For instance when I

<?php
var_dump(wire()->users->find('id>0')); // lists all users

I get an output like this


object(ProcessWire\PageArray)#330 (7) {
  ["hooks"]=>
  array(2) {
    ["PageArray::render"]=>
    string(60) "MarkupPageArray->renderPageArray() in MarkupPageArray.module"
    ["PageArray::renderPager"]=>
    string(56) "MarkupPageArray->renderPager() in MarkupPageArray.module"
  }
  ["count"]=>
  int(2)
  ["items"]=>
  array(2) {
    [0]=>
    string(23) "/pw/access/users/admin/"
    [1]=>
    string(23) "/pw/access/users/guest/"
  }
  ["total"]=>
  int(2)
  ["start"]=>
  int(0)
  ["limit"]=>
  int(0)
  ["selectors"]=>
  string(45) "id>0, sort=sort, parent_id=29, templates_id=3"
}

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...