MartynLearnsPHP Posted March 6, 2015 Share Posted March 6, 2015 I have been working on a private message board, but have become unstuck with one small cosmetic detail. When someone receives a new message I can identify this on their page, but when they go to their message page I want them to be able to see which message is the new one (they might have 3 or 4 messages and so they will need to see which ones they have read as they go along. I am currently working with 2 databases to manage this. A 'members' which holds all the member information and 'conversation' which holds all the conversation dialogue. The conversation dialogue has the following columns: id: auto increment originalid: which holds the id reference from when the conversation was started so that all discussion in that conversation can be stringed together. The conversations need to be separated out because two members might have different discussion going on regarding different projects member1: who is the sender of the message member2: who is the message recipient title: which is the discussion subject matter read1: which shows whether member1 has read the message read2: which shows whether member2 has read the message message: which is obviously the body of the message sent removed1: if member1 deletes the message from the inbox removed2: if member2 deletes the message from their inbox timestamp: when posted I have a page whereby the member views their list of private discussion. From here they can click on the subject title to open the discussion thread in a side bar. It all works perfectly, except I want discussions with an unread message to state that they are new. My code is as follows, but the "NEW" tag isn't appearing beside discussions with unread messages in them. Can anyone see what I have done wrong? (for reference $memberid is the id of the logged in member). <div id="collapseInbox" class="inbox-cont panel-collapse collapse in"> <div class="panel-body"> <div class="inbox-main"> <?php $query2 = DB::getInstance()->query("select c.id as cid, c.originalid, c.title, max(c.time) as timestamp, m.id as membersid, m.username, m.member_first_name, m.member_last_name from conversation as c, members as m where ((c.member1='{$memberid}' and c.read1='Yes' and c.removed1='No' and m.id=c.member2) or (c.member2='{$memberid}' and c.read2='Yes' and c.removed2='No' and m.id=c.member1)) group by c.originalid order by MAX(c.id) DESC"); foreach ($query2->results() as $result2) { echo "<div class='inbox-message'> <span class='inbox-from'>" . htmlentities($result2->member_first_name) . " " . htmlentities($result2->member_last_name) . " (" . htmlentities($result2->username) . ") </span> <span class='inbox-title'> <form action='' method='post'> <input type='hidden' name='id' id='id' value='" . $result2->cid . "'> <a href='#$result2->cid' onClick='showMessages(" . $result2->cid . ")' data-toggle='tooltip' data-original-title='View message'>" . htmlentities($result2->title) . "</a>"; if ($result2->member1=='$memberid' && $result2->read1=='No') {echo " <font color = #920505><b>NEW</b></font>"; } else { if ($result2->member2=='$memberid' && $result2->read2=='No') {echo " <font color = #920505><b>NEW</b></font>";} } echo "</form> </span> <span class='inbox-date'>"; echo timeAgo(strtotime($result2->timestamp)); echo "</span> </div>"; } if ((intval($query1->count()==0)) && (intval($query2->count()==0))) { echo "<div class='inbox-message'> <span class='inbox-from'> You have no messages. </span> </div>"; } ?> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="js/messages.js"></script> </div> </div> </div> Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/ Share on other sites More sharing options...
QuickOldCar Posted March 6, 2015 Share Posted March 6, 2015 Looks like you only return read messages that are Yes in your query where ((c.member1='{$memberid}' and c.read1='Yes' and c.removed1='No' and m.id=c.member2)or (c.member2='{$memberid}' and c.read2='Yes' and c.removed2='No' and m.id=c.member1))group by c.originalid order by MAX(c.id) DESC" Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507798 Share on other sites More sharing options...
MartynLearnsPHP Posted March 7, 2015 Author Share Posted March 7, 2015 I'm afraid that wasn't the solution. Sorry, I had already done that but copied old text. That part of the equation should be: $query2 = DB::getInstance()->query("select c.id as cid, c.originalid, c.title, max(c.time) as timestamp, c.read1, c.read2, c.member1, c.member2, m.id as membersid, m.username, m.member_first_name, m.member_last_name from conversation as c, members as m where ((c.member1='{$memberid}' and c.removed1='No' and m.id=c.member2) or (c.member2='{$memberid}' and c.removed2='No' and m.id=c.member1)) group by c.originalid order by MAX(c.id) DESC"); foreach ($query2->results() as $result2) I am convinced that the error is in the line of code that reads: if ($result2->member1=$memberid and $result2->read1=='No') { echo " <font color = #920505><b>NEW</b></font>"; } else { if ($result2->member2=$memberid and $result2->read2=='No') { echo " <font color = #920505><b>NEW</b></font>"; } } But I can't figure out why that is. Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507808 Share on other sites More sharing options...
QuickOldCar Posted March 7, 2015 Share Posted March 7, 2015 need a comparison operator == if ($result2->member1==$memberid and $result2->read1=='No'){ echo " <font color = #920505><b>NEW</b></font>";} else { if ($result2->member2==$memberid and $result2->read2=='No'){ echo " <font color = #920505><b>NEW</b></font>";} Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507824 Share on other sites More sharing options...
QuickOldCar Posted March 7, 2015 Share Posted March 7, 2015 font is deprecated should use css echo " <div style='color: #920505;font-weight: bold;'>NEW</div>"; I would even position it and so on versus returning a new line Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507825 Share on other sites More sharing options...
MartynLearnsPHP Posted March 7, 2015 Author Share Posted March 7, 2015 Doublle == still isn't solving it. My latest effort, which still isn't working, is: if (($result2->member1==$memberid && $result2->read1=='No') || ($result2->member2==$memberid && $result2->read2=='No')) { echo " <font color = #920505><b>NEW</b></font>"; } Just for a point of reference, if I replace the == with = throughout this whole bit of code, it puts the "NEW" message next to every discussion in the list. Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507829 Share on other sites More sharing options...
boompa Posted March 7, 2015 Share Posted March 7, 2015 Just for a point of reference, if I replace the == with = throughout this whole bit of code, it puts the "NEW" message next to every discussion in the list. That would seem to indicate that the problem is the $memberid variable is not matching the result members you're testing. Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507836 Share on other sites More sharing options...
MartynLearnsPHP Posted March 7, 2015 Author Share Posted March 7, 2015 $memberid is definitely correct. It is the id of the logged-in user and is used endlessly throughout the site. It is also used in the main $query2 select to identify all the messages for that member which is working correctly. Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507837 Share on other sites More sharing options...
MartynLearnsPHP Posted March 7, 2015 Author Share Posted March 7, 2015 (edited) Aha! I think I've had a kind of breakthrough. I just need to figure out how to get around it. My code is currently producing a grouped result of messages within one subject matter. What I need to do is find out whether there is a single item within that group where either the condition if (($result2->member1=='$memberid' && $result2->read1=='No') || ($result2->member2=='$memberid' && $result2->read2=='No')) {echo " <font color = #920505><b>NEW</b></font>";} is being met. Edited March 7, 2015 by MartynLearnsPHP Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507841 Share on other sites More sharing options...
MartynLearnsPHP Posted March 8, 2015 Author Share Posted March 8, 2015 OK. This is really starting to blow my mind. I have this lovely group of data that Groups all of the data into a nice column of discussions. As so: $query2 = DB::getInstance()->query("select c.id as cid, c.originalid, c.title, max(c.time) as timestamp, c.read1, c.read2, c.member1, c.member2, m.id as membersid, m.username, m.member_first_name, m.member_last_name from conversation as c, members as m where ((c.member1='{$memberid}' and c.removed1='No' and m.id=c.member2) or (c.member2='{$memberid}' and c.removed2='No' and m.id=c.member1)) group by c.originalid order by MAX(c.id) DESC"); foreach ($query2->results() as $result2) I then want that list to be echoed out so that a user can view the lists. And again, that is working fine. However, I want to have one argument that puts a "NEW" message next to any items on the list where the list contains one item that has ($results2->member1==$memberid && read1=='No') OR ($results2->member2 && read2=='No') within the group. But I just can't seem to get that argument working. Any suggestions? Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507853 Share on other sites More sharing options...
MartynLearnsPHP Posted March 8, 2015 Author Share Posted March 8, 2015 Aha! I've made another small step forward. Not so much in resolving the problem, but in identifying the cause. I've tried echoing out all the results, and my code is identifying the first line in my database as the one to reference, whereas it will always be the last line that has not been read. So I need my "if" statement to select the last line in the search option. Anyone know how I can do this> Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507854 Share on other sites More sharing options...
mac_gyver Posted March 8, 2015 Share Posted March 8, 2015 group by c.originalid didn't read through every word in this thread, but using GROUP BY in the query consolidates all the rows with the same c.originalid value together into a single row in the result set. so, even if your query matches several rows that have member1/member2 values that match $memberid, the only data that will be in this consolidated row will be from the first row in the group, before the group by consolidated them into a singe row. dumping each row in your result set, using var_dump()/print_r(), would show you what you are actually getting. Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507856 Share on other sites More sharing options...
MartynLearnsPHP Posted March 8, 2015 Author Share Posted March 8, 2015 (edited) Thanks, mac_gyver. That information is a huge help because it points me in the direction I should be going (or rather puts a big 'Road Closed' sign in the route that I was trying to follow). It's bedtime for me now, but tomorrow I will look at implementing a seperate "Select Search" where I don't group them and then cross reference originalid with the group search. If they match? Then that is the unique link that I am looking for and will hopefully give me the result that I need. Edited March 8, 2015 by MartynLearnsPHP Quote Link to comment https://forums.phpfreaks.com/topic/295149-condition-within-a-foreach-loop/#findComment-1507858 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.