spoetnik Posted April 15, 2020 Share Posted April 15, 2020 I have products referencing to brands using a page reference field. Now I want a list of brands, ordered by number of references. I found the function $page->references(), but how do I sort this? <?php $brands = $pages->find('template=brand'); $data = ''; foreach($brands as $brand) { if ($brand->references()->count()) { $data .= "<li class='list-inline-item'><a href='/auctions/?brand=$brand->id'>$brand->title</a></li>"; } } echo $data; ?> Thanks for any suggestions! Link to comment Share on other sites More sharing options...
Jan Romero Posted April 15, 2020 Share Posted April 15, 2020 It’s actually really easy: $brands = $pages->find('template=brand'); echo $brands->sort('-numReferences')->each("<li>{title}: {numReferences}"); Whether it’s very efficient is a different story. I wouldn’t know. Be aware that you have to sort the PageArray. Putting it in the find() selector won’t work. Edit: actually, you probably want hasReferences, as per the documentation: $numReferences Total number of pages referencing this page with Page reference fields. $hasReferences Number of visible pages (to current user) referencing this page with page reference fields. 3 Link to comment Share on other sites More sharing options...
spoetnik Posted April 15, 2020 Author Share Posted April 15, 2020 Thanks a lot! Link to comment Share on other sites More sharing options...
Jan Romero Posted April 15, 2020 Share Posted April 15, 2020 Btw, if you’re going to do $page->references()->count(), you will be better off telling references() that you just need the cound directly. In the end, these methods and properties all end up in FieldtypePage and provide some efficiency tricks like this. However, this will always query the database for every page in your array and every page field in your system, so if you want to get real gainz, you're probably best off just asking the database for your pages and the count somewhat like this: $query = wire('database')->prepare('select data, count(paged_id) from field_yourpagefield group by data'); $query->execute(); $results = $query->fetchAll(\PDO::FETCH_KEY_PAIR); $brands = wire('pages')->getById(array_keys($results), ['template' => wire('templates')->get('brand') , 'findTemplates' => false , 'getNumChildren' => false , 'joinSortfield' => false]); echo $brands->each(function ($brand) { return '<li>' . $brand->title . ' was referenced ' . $results[$brand->id] . ' times.'; }); At least that is what I was going to write reflexively before checking the core for something ready-made. That's the amazing thing about ProcessWire, that something like this just already exists and makes everything super easy. 3 Link to comment Share on other sites More sharing options...
spoetnik Posted April 15, 2020 Author Share Posted April 15, 2020 Thanks for you answer. Actually I don't need the count, but don't want any "Brands" without references. This is my final code: <ul class="list-inline"> <?php $brands = $pages->find('template=brand'); $brands = $brands->sort('-numReferences'); $brandCount = 0; foreach($brands as $brand): if($brandCount > 5) break; if ($brand->hasReferences) { $brandCount ++; echo "<li class='list-inline-item'><a href='/auctions/?brand=$brand->id'>$brand->title</a></li>"; } endforeach; ?> </ul> Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now