5

I'm writing a plugin that adds or updates users profiles in Craft from a JSON file. Every user profile could have a lot of custom fields in the future which store a lot of data. To check if a user exist and if its data is up to date with the data in the JSON file, I need to retrieve 2 fields from every user profile. Is that possible with the elementCriteriaModel?

I've seen examples of the criteriaModel by which you filter which users are returned by adding parameters. And then you get an array back filled with users that match the criteria and all of their custom fields.

But I need all users returned, but not with all their custom fields. Because I think that will slow things down. Is it possible to fetch all users but returning only 2 specific fields by using the criteria model? Or some other way? I know I can filter the results afterwards and return another array, but then the slow database query is allready been made. I want to limit the amount of queries made and the amount of data retrieved to the bare necessities.

1 Answer 1

3

Not 100% certain, but I suspect that with a standard ElementCriteriaModel it's all or nothing, as craft generally returns the full userModel including all custom fields. If you're worried about memory limitations, then you might want to either process the users in batches and/or create your own custom query. Something like this perhaps:

// define query
$criteria = craft()->elements->getCriteria(ElementType::User);

$query = craft()->elements->buildElementsQuery($criteria);
$query->select(array('elements.id AS id', 'field_extid AS extid', 'field_lastupdatetime AS lastupdatetime'));
$query->limit(null);
$results = $query->queryAll();

foreach($results as $result)
{
    // compare craft values to json

    // var_dump($result['extid']) // uncomment to test
    // var_dump($result['lastupdatetime']) // uncomment to test
    // set $userExists equal to true or false if needed

    // create/retrieve user
    if ($userExists) {
        $user = craft()->users->getUserById($result['id']);
    } else {
        $user = new UserModel();
    }

    // update, save, etc
    // ...
}

You can also use var_dump($results) to test whether you are getting the expected results.

11
  • I have no idea what to fill in here: $query->select(array('elements.id AS id', 'field_myField1 AS myField1', 'field_myField2 AS myField2')); Could you be a bit more specific? My fields are called extid and lastupdatetime. The id on which I will have to find my users is not the craft id but the extid field. Apr 14, 2015 at 18:41
  • I updated the field names and added some notes. See if that helps at all. I would still keep the craft element id as you will need that to eventually retrieve the user. Apr 14, 2015 at 19:09
  • After a lot of trial and error, I came upon the same SELECT statement, but it just turns up empty... And I do have users in my database :) I'm looking at the actual database too to understand what the SELECT is supposed to do, but I just don't see it... Don't I have to add a WHERE statement somewhere? So it knows it should compare the elements.id property? Apr 14, 2015 at 19:13
  • I tried it myself, and it doesn't like the $query->limit('none');. Try removing that line. Apr 14, 2015 at 19:21
  • Allright, after some serious brainhurting thinking I understand what I'm doing here. And why the array just kept returning empty. It seems that the limit('none') is returning an empty array. When I delete that line it works! Thanks! Apr 14, 2015 at 19:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.