Jump to content

Faster way to merge user data into my page array?


Recommended Posts

I have created a page with template "portfolio-detail" for every user's that's registered on my site, linked to by a field that stores their user ID.

Now I want to be able to grab that user and integrate them with the page selector as neatly as possible. The reason for this approach is that the page, rather than the user, has many things built around it already, other fields, parent structures, etc. that are fundamental to filtering, url structure etc.

I currently have this, but it means a separate query to the user table for every single user. This works, but a) I'm sure it could be faster/neater and b) it means I can only access their details with $profile->user->user_field instead of just $profile->user_field

$profiles = $pages->find("template=portfolio-detail");
foreach($profiles as $profile) {
    $user = $users->get("id={$profile->user_id}");
    $profile->user = $user;
}

Is there a better way?

Link to comment
Share on other sites

I'm not sure what you're aiming at, but is it that you want to find pages based on both what is in the portfolio-detail page and in the user page?

If so, one approach might be to do something like this (not tested):

$userIDs = implode('|', $pages->findIDs("template=user, title%=sometext"));
$profiles = $pages->find("template=portfolio-detail, user_id={$users}, another_field%=someothertext");

 

  • Thanks 1
Link to comment
Share on other sites

Hi Bill, thanks for looking

Not exactly. Although I have done something very similar to what you suggested already, in order to limit which portfolio's I'm getting based on something in the user details, so you were bang on the money on how to do that.

All I really want, is to select portfolio-detail items, and have all the details from a matching user available to me in that selection.

Eg, I've got a user like this

$user->id = 392;
$user->name = 'email_example.com';
$user->firstname = 'Jane';
$user->lastname = 'Doe';
$user->avatar = PageImage;

And I've got portfolio detail pages like this

$portfolio->title = 'Jane Doe';
$portfolio->user_id = 392;

The former has all the data I want to grab for each item. But the latter has all the details I need to organise my site like URLs, tags, parent pages, etc.

So I just want to kind of... merge them together neatly.

Link to comment
Share on other sites

I think the "correct" way to do it, is how you have it implemented now: for each portfolio, you query the related user to obtain the additional data. It's true that if you are constantly making queries of this type (ex: inside a loop), that performance is not optimal. Maybe if you use some kind of page/template cache you can solve it.

Another way could be to keep a copy of the user's data in a "user" field of the portfolio template (using a textarea field and save all user data in JSON, or use the new ProFields Combo field) and implement a synchronization system based on hooks, then in the users' Page Save hook, find the related portfolio and updates that JSON field.

🤷‍♂️

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

8 hours ago, cjx2240 said:

All I really want, is to select portfolio-detail items, and have all the details from a matching user available to me in that selection.

What sort of field is user_id? If it's an integer or text field that only stores the ID (I assume it is because of the name and way you are getting the user page via the ID) then you should change to a "user_page" Page Reference field that will hold the actual User page object.

On the Advanced tab of the settings for the user_page field tick the Autojoin checkbox. That way the User object associated with each portfolio-detail page will automatically be loaded in a single database query when you do...

$profiles = $pages->find("template=portfolio-detail");

...rather than needing multiple database queries within the foreach.

In the foreach you will get the field values from the User object like this:

echo $portfolio->user_page->firstname;

 

  • Like 2
Link to comment
Share on other sites

The post from @Robin S deals with your issue nicely, I think, but it might also be worth a look at the links in this discussion:

The ConnectPageFields module uses methods similar to the synchronization suggested by @Pixrael. And owner selectors look interesting, though I've never tried them.

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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...