This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation

Assumptions, Prep, and General Notes

  1. Public Registration is enabled (see your Dashboard > System & Settings > Login & Registration > Public Registration).

  2. Public Profiles is enabled (see your Dashboard > System & Settings > Login & Registration > Public Profiles).

  3. It can be useful to segregate the PM inbox into a tab (see how-to here), especially if you also show other user information in the profile. (The demo screenshots at the end of this post shows tabs, although the exampled doesn't include that code. Effectively, to add tabbed viewing to the conditional display logic, you just need to make sure that the entire tab div is wrapped in the "if ($u->isRegistered() && $u->getUserID() == $profile->getUserID()" clause) .


Create controller and view overrides

First read about overriding 5.6 core controllers.

  1. Add a "profile" folder in your [root]/single_pages folder.

  2. Add a "single_pages" folder in your [root]/controllers folder.

  3. Copy [root]/concrete/single_pages/profile/view.php to [root]/single_pages/profile/view.php

  4. Copy [root]/concrete/core/controllers/single_pages/profile.php to [root]/controllers/profile.php and modify the class statement per the aforementioned override instructions


Extend the profile controller

In [root]/controllers/profile.php...

Add this at the bottom of public function view()...

        // You have x new messages
        $this->set('newMsgsCount',$this->getNewMessageCount());
        
        // You have x saved (non-new) messages
        $this->set('totMsgsCount',$this->getTotMessageCount());
        
        // Message subjects
        $this->set('msgInfo',$this->getMsgInfo());

Next, add the following functions at the end of the class:

    function getNewMessageCount() {
        $u = new User();
        $uID = $u->getUserID();
        $db = Loader::db();
        $countnew = $db->getOne("SELECT COUNT(*) FROM UserPrivateMessagesTo WHERE msgIsNew = 1 AND uID = ?",array($uID));
        $this->set('newMsgsCount',$countnew);
            
    }
    
    function getTotMessageCount() {
        $u = new User();
        $uID = $u->getUserID();
        $db = Loader::db();
        $countall = $db->getOne("SELECT COUNT(*) FROM UserPrivateMessagesTo WHERE uID = ?",array($uID));
        $countnew = $db->getOne("SELECT COUNT(*) FROM UserPrivateMessagesTo WHERE msgIsNew = 1 AND uID = ?",array($uID));
        $oldmsgs = $countall-$countnew;
        $this->set('totMsgsCount',$oldmsgs);
    }
    public function getMsgInfo() {
        $u = new User();
        $uID = $u->getUserID(); 
        $db = Loader::db();
        
        $mq = $db->Execute("SELECT UserPrivateMessages.msgID, UserPrivateMessages.msgDateCreated, UserPrivateMessages.msgSubject, UserSearchIndexAttributes.ak_firstname, UserSearchIndexAttributes.ak_lastname FROM UserPrivateMessages JOIN (UserPrivateMessagesTo JOIN UserSearchIndexAttributes ON UserSearchIndexAttributes.uID = UserPrivateMessagesTo.uAuthorID) ON UserPrivateMessages.msgID = UserPrivateMessagesTo.msgID WHERE UserPrivateMessagesTo.uID = ? AND UserPrivateMessagesTo.msgIsNew = 1 AND NOT UserPrivateMessages.uAuthorID = UserPrivateMessages.uToID;",array($uID));
        
        $messages = array();
        while($my_data = $mq->FetchRow()){
        $messages[] = $my_data;
        }
    
        $this->set('my_data', $messages);   
    }   

The getMsgInfo() function basically queries various db tables to figure out if the current user has unread messages. You may need to modify the query to fit the way your own C5 is set up. The specific query shown will work ONLY if you have the custom attributes with the handles of "firstname" and "lastname" added AND searchable from the user profile. Such attributes (and their handles) can be defined in the Dashboard > Users > Attributes section.

If you have other custom attributes defined---specifically, attributes you want to display in the new message summary---you can use those instead, but you'll need to correspondingly modify the "ak_" variables in both the control and view examples.

If you DON'T have custom user attributes at all, you can remove everything in UserSearchIndexAttributes from the query SELECT statement and instead use users.uName. In that case, you'll also need to do your JOIN on users.uID

If you do have custom user attributes, but want to correlate messages with a non-searchable (i.e., non-indexed) attribute...well, it's probably still possible but would require a complex query that somehow joined Users with atDefault or atBoolean via some other tables. That's beyond the scope of this How To, but can (again, probably) be done.


Modify the profile view

To add your freshly-gathered message info to your profile view, include something like this in your [root]/single_pages/profile/view.php (below the ccm-profile-body-attributes div):

<?php if ($u->isRegistered() && $u->getUserID() == $profile->getUserID()) { ?>

    <div class="pmlist" style="margin-top: 1em;">
        <?php

        if ($newMsgsCount > 0) {
            $message = "<div class=\"margin_b_1em\">You have $newMsgsCount new messages and $totMsgsCount saved messages.</div>";
            echo $message; 
        } else {
            $message = "<div class=\"margin_b_1em\">You have no new messages and $totMsgsCount saved messages.</div>";
            echo $message; 
        }
        ?>      
        <table width="100%" border=0>
            <tr>
             <td><?php echo t('<b>Sender</b>') ?></td>
             <td><?php echo t('<b>Message Sent</b>') ?></td>
             <td><?php echo t('<b>Subject</b>') ?></td>
            </tr>
            <?php

            foreach($my_data as $row){
            ?>
             <tr>
              <td><?php echo $row['ak_firstname'].' ' .$row['ak_lastname']?></td>
              <td><?php echo $row['msgDateCreated']?></td>
              <td><a href="<?php echo $this->url('profile/messages/view_message/inbox/',$row['msgID']); ?>"><?php echo $row['msgSubject'] ?></td>
            </tr>
            <?php} ?>
        </table>
        <br />
        <p><a href="/messages/view_mailbox/inbox/">Go to Inbox</a></p>
    </div>
    <?php } ?>

Note that this example reflects the specific logic in the previous controller example, including both default and custom user attributes ("ak_firstname" and "ak_lastname"). If you don't have custom attributes and only want to display standard user data, replace the custom "ak_" attributes in the example with the user name.


Testing

Testing that the new function works is fairly easy. You'll want to test that the current user can see their own messages, that guests and other logged-in users can't see other users' messages. To do this:

  • Log in as a user other than yourself (create a new dummy user if you don't want to use someone else's account).

  • Search users for yourself and send yourself a test message.

  • Log out.

  • Log back in under your own account and go to your profile. You should see that you have (at least) one message listed.

  • Go to any other user's profile. In profiles that are not you, you shouldn't see a message list (or tab, if you've added that) at all.

  • Go back to your own profile and click through the test subject link to read the message. When you return to your profile view, the test message should be gone from the new-message list. If it was your only message you should also see that you have one "saved" message and "0" new messages.

At the end of the day, your new inbox summary should behave like this (the profile views are modified in several ways, too, but the "Your Messages" tab is the net-net of this How To):

If you're not the user, it should look like this (img), and

If you are the user it should look like this (img)


I hope this all works for you. If it doesn't, I've probably just forgotten to explain something, so feel free to PM me.

Loading Conversation