rick Posted August 12, 2019 Posted August 12, 2019 Howdy all, Is there a means to return pages sorted by star ratings? I apologize if I have missed a topic, but I haven't found anything related with my searches. Thanks for your help!
dragan Posted August 12, 2019 Posted August 12, 2019 @rick Are you talking about FieldtypeStarRating? Perhaps you should better post it in the support forum thread instead. Anyway: did you already try to sort by that field and it failed? Give us some code examples of what you've already tried, so we can get a better picture of your setup etc. 1
rick Posted August 12, 2019 Author Posted August 12, 2019 (edited) @dragan, I'm using the core comments with star rating field type. Yes, the test code doesn't return any errors... // Tracy console $p = wire('pages')->get('template=my_template,include=all'); if($p->hasChildren) { $pc = $p->children('sort=stars, limit=12'); // One of many combinations I've tried d($pc); } But the results (12) are not sorted by stars, rather the results are returned in the order the pages were created (Id)... total => 34 start => 0 limit => 12 pager => "1 to 12 of 34" (13) items => array (12) Page:0 => array (5) ... Page:11 => array (5) selectors => "parent_id=1026, sort=stars, limit=12, status<1024" (49) [edit] Also, each template has the comments (fieldtypecomment) and stars are enabled. Edited August 12, 2019 by rick Additional info
dragan Posted August 12, 2019 Posted August 12, 2019 Well, I have never used this inputfield type, but did you also try sort=stars.count ? 1
rick Posted August 12, 2019 Author Posted August 12, 2019 Yes Sir, I've tried a few combinations with the same results. I haven't seen anything in the source regarding an average other than the public function stars itself.
rick Posted August 12, 2019 Author Posted August 12, 2019 For other's and my reference: Sorting pages by stars requires the comment field name prefix, eg: // From previous post... $pc = $p->children('sort=-comments.stars, limit=12'); // Returns pages with 5 stars, then 4.5 stars, etc. I must have mistyped the comment field name before. My apologies. Thanks for your help @dragan. 2
wbmnfktr Posted August 12, 2019 Posted August 12, 2019 And that shows the highest rated comments? N-e-v-e-r used them actually. But still interesting to know for an upcoming idea.
rick Posted August 12, 2019 Author Posted August 12, 2019 @wbmnfktr Yes it does. Even the fractional star rating, eg, 5, 4.75, 4.5 ... to 0 works.
wbmnfktr Posted August 13, 2019 Posted August 13, 2019 I really hate dealing with comments - due to GDPR and such - but maybe I should give it a try. (Kind of) Glad you pushed me into this direction with your question. 1
rick Posted August 13, 2019 Author Posted August 13, 2019 Well, sorting by stars seems to not work. When I expand the test data the sort fails. Here is the tracy test code... $p = wire('pages')->findMany('template=my_template,sort=-comments.stars,include=all,limit=12');//34 total pages foreach( $p as $m ) { $stars = $m->comments->renderStars(true, array('schema'=>'microdata','partials'=>true)); echo $m->id.': '.$stars.'<br />'; } which gives the following results... 1027: ★★★★★4/5 (7 ratings) 1068: ★★★★★★4.3/5 (6 ratings) 1148: ★★★★★★3.8/5 (17 ratings) 1086: ★★★★★★4.3/5 (10 ratings) 1056: ★★★★★★4.5/5 (2 ratings) 1114: ★★★★★4/5 (9 ratings) 1057: ★★★★★4/5 (7 ratings) 1120: ★★★★★★4.8/5 (8 ratings) 1121: ★★★★★5/5 (3 ratings) 1063: ★★★★★★3.8/5 (12 ratings) 1064: ★★★★★5/5 (1 rating) 1065: ★★★★★★4.4/5 (14 ratings) Also notice that some ratings display 6 stars. The default config is set to 5. I am not concerned with sorting by the number of ratings, only the average ratings. Anyone have an idea what I am doing wrong?
rick Posted August 14, 2019 Author Posted August 14, 2019 Okay, here is a workaround. I call it a workaround, because one, it works for what I need, and two, this will present problems when I have to process all 5K+ pages for each of the three parent pages in this current project. Here is the tracy code: $p = $pages->findMany("template=my_template"); // 34 total $s = array(); foreach( $p AS $m ) { $s[$m->id] = $m->comments->stars(true); } arsort($s); $s = array_slice($s,0,12,true); d($s); Produces this result: array (12) 1064 => 5.0 1121 => 5.0 1120 => 4.75 1056 => 4.5 1065 => 4.43 1054 => 4.41 1068 => 4.33 1086 => 4.3 1122 => 4.29 1062 => 4.25 1127 => 4.25 1058 => 4.22 1
Robin S Posted August 15, 2019 Posted August 15, 2019 14 hours ago, rick said: this will present problems when I have to process all 5K+ pages for each of the three parent pages in this current project Using the brand new "multiple methods" hook feature in PW 3.0.137 you could save the average stars value to a decimal (or float) field every time a comment is approved/disapproved/updated/deleted. Then you can find or sort pages by the field more efficiently. The hook below assumes a comments field named "comments" and a decimal field named "decimal": $wire->addHookAfter('FieldtypeComments::commentApproved, FieldtypeComments::commentUnapproved, FieldtypeComments::commentDeleted, FieldtypeComments::updateComment', function(HookEvent $event) { /* @var Page $page */ $page = $event->arguments(0); /* @var Field $field */ $field = $event->arguments(1); if($field->name !== 'comments') return; if($page->template->hasField('decimal')) { // Save the average star rating for comments with approved or featured status $page->setAndSave('decimal', $page->comments->find("status=1|2")->stars(true)); } }); P.S. You'd do a one-off API operation to save the average stars value for all your existing comments to get things set up initially. 3
rick Posted August 15, 2019 Author Posted August 15, 2019 Thanks @Robin S! That is a great solution. I'll close this out now. 1
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