LostKobrakai Posted November 10, 2014 Share Posted November 10, 2014 I'm currently rebuilding a pagination to a custom one. Now I have an issue with $list->getTotal(). If I ommit the limit selector I count 16 entries, but getTotal() return me 17. After testing it, it seems my manual sorting is playing tricks. $conversations = $page->children($selector); var_dump(count($conversations), $conversations->getTotal()); $notRead = new PageArray(); foreach($conversations as $conversation){ //Check children (messages) for read status if(count($conversation->children("read_by!=$user"))){ $notRead->prepend($conversation); $conversations->remove($conversation); } } var_dump(count($conversations), $conversations->getTotal(), count($notRead), $notRead->getTotal()); $conversations->prepend($notRead); var_dump(count($conversations), $conversations->getTotal()); This outputs: 13, 13 11, 11, 2, 2 13, 14 Has anyone else noticesed something similar? To me it seems, like theres something wrong with the calculation. Link to comment Share on other sites More sharing options...
kongondo Posted November 10, 2014 Share Posted November 10, 2014 This behaviour is documented here: http://processwire.com/api/arrays/page/ $p->getTotal() Get the total number of pages that were found from a $pages->find("selectors, limit=n") operation that led to this PageArray. The number returned may be greater than the number of pages actually in this PageArray instance, and is used for calculating pagination. Whereas $p->count() will always return the number of pages actually in this PageArray instance. Link to comment Share on other sites More sharing options...
LostKobrakai Posted November 11, 2014 Author Share Posted November 11, 2014 I try to build a pagination, so I know about this. But I only reorder the pages and suddenly I get another total number, which seems weird. I just removed the limit to test that there are not more entries. Link to comment Share on other sites More sharing options...
horst Posted November 11, 2014 Share Posted November 11, 2014 hmm, pagination without limit? Link to comment Share on other sites More sharing options...
LostKobrakai Posted November 11, 2014 Author Share Posted November 11, 2014 I notices the wrong getTotal() value, while working with a limit. I removed it, so I can use count to check that there's indeed not a single page more in the pagearray than there should be. It was just a matter of finding out where the error was. Nobody an idea why this kind of sorting does change the total number? Link to comment Share on other sites More sharing options...
Soma Posted November 11, 2014 Share Posted November 11, 2014 PageArray->prepend($item) originally was only for one item and import() was only for adding PageArray. This was added to support arrays for all add() prepend() append() etc. Looks like the prepend() has a bug where it counts ++ when prepending multiple items. It works correct if using append() or add(). If you use foreach to add via prepend(item) it works also correct. Maybe file an issue? 1 Link to comment Share on other sites More sharing options...
LostKobrakai Posted November 11, 2014 Author Share Posted November 11, 2014 Thanks Soma, will do so on github. Just wasn't sure if it's a bug. Link to comment Share on other sites More sharing options...
Soma Posted November 11, 2014 Share Posted November 11, 2014 This is the current public function prepend($item) { parent::prepend($item); $this->numTotal++; return $this; } and should be maybe like this rather public function prepend($item) { parent::prepend($item); $this->numTotal = $this->count; return $this; } in PageArray.php Link to comment Share on other sites More sharing options...
LostKobrakai Posted November 11, 2014 Author Share Posted November 11, 2014 I just changed the way I stitched the two PageArray's back together to this for now. $conversations = $notRead->append($conversations); Link to comment Share on other sites More sharing options...
Soma Posted November 11, 2014 Share Posted November 11, 2014 Or simply do a foreach foreach($notRead as $n) $conversations->prepend($n); I think regarding what you seem to be doing, you add a children page to a page with a reference to a user read the article? This may create performance problems and you already doing work to get it out list via a double searching/filtering. Not sure what would be a better way, since you seem to like the notread on top? So a sorting by it is difficult. Maybe some more thinking would reveal a more scalable/easier way to do this.. Anyway if the children grow and you do it the way you do it will create performance issue: This: (count($conversation->children("read_by!=$user")) Should be if($conversation->count("read_by!=$user")) ... Or this if($conversation->child("read_by!=$user")) Link to comment Share on other sites More sharing options...
LostKobrakai Posted November 11, 2014 Author Share Posted November 11, 2014 It's not about articles. I have conversations with all the messages as children. The messages all do have a pagefield, which stores the people who have already "read" this message. In this bit I load all the conversations a user is part of and sort the conversations, which do have unread messages, first. I don't know if there would be a better way to sort the conversations this way. The only one I can imagine right know is by using two different selectors. Link to comment Share on other sites More sharing options...
kongondo Posted November 11, 2014 Share Posted November 11, 2014 (edited) Regarding selectors, don't know if OR-groups, Group, sub-selectors would be relevant in your case? https://processwire.com/talk/topic/3768-processwire-dev-branch/page-10#entry64049 https://processwire.com/talk/topic/7370-search-for-one-field-or-another-but-with-different-values/ https://processwire.com/talk/topic/3768-processwire-dev-branch/page-9#entry58722 Edit...hmmm, maybe not...not sure these would be helpful... Edited November 11, 2014 by kongondo Link to comment Share on other sites More sharing options...
Soma Posted November 11, 2014 Share Posted November 11, 2014 Ah. Well difficult one. All I know is that this is possible, but doesn't help and work in this case. $pages->find("template=basic-page, sort=-children.count"); After some thinking, the best (I think) way with stuff already there, would be to mabye store the conversations to a page field on the user. Then remove read conversations from the page field. If a message is created, the conversation/topic page will be added to all users page field once (the overhead has to go somewhere? And if done via direct sql to insert id's to page field it's fast even for thousands of users). // get the unread messages ids (1231|32232|2323|1233...) $unreadIDs = $user->unread_conversations; // OR groups either ids or parent $conversations = $pages->find("(id=$unreadIDs), (parent=/conversations_parent/), limit=3"); // output entries, ids unread should be on top? (can't test here) foreach($conversations as $conv){ $class_unread = $user->unread_conversations->has($conv) ? "unread" : "read"; echo "<p class='$class_unread'>$conv->title</p>"; } // render pager echo $res->renderPager(); Link to comment Share on other sites More sharing options...
LostKobrakai Posted November 12, 2014 Author Share Posted November 12, 2014 Shouldn't something like this work? messages is a PageTable field, which includes all the children aka messages. The first one should get all conversations without the ones where all messages were read by the user. The second one should get all the conversations which don't have a message, which the user not read. $unread = $pages->find("…, users=$user, limit=10, !messages.read_by=$user"); $read = $pages->find("…, users=$user, limit=10, !messages.read_by!=$user"); Link to comment Share on other sites More sharing options...
kongondo Posted November 14, 2014 Share Posted November 14, 2014 (edited) Seems you didn't really read my post #12 here: https://processwire.com/talk/topic/8244-gettotal-returns-wrong-value/?p=80042 Edited November 14, 2014 by kongondo Link to comment Share on other sites More sharing options...
LostKobrakai Posted November 14, 2014 Author Share Posted November 14, 2014 @soma I added the read_by field to the conversations as well, so I can query by conversation not read as well as message not read. I also tried your idea with the or group, but it does not work. The pages as neither sorted by read / unread nor by time. // Conversationes the user is part of $selector = "template=conversation, users=$user, sort=-time"; if($input->whitelist("conversation-search")){ $q = $input->whitelist("conversation-search"); $selector .= ", (title|messages.text_singular*=$q), (users.firstname|users.lastname=$q)"; } $unread = $pages->find($selector.", read_by!=$user"); $conversations = $pages->find("(id=$unread), (".$selector.", read_by=$user), limit=10"); 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