Working with Private Messages

I’m trying to pull some private message functionality into various parts of a site I’m building.
I didn’t see anything about working with this feature in the docs, just that it exists.
Is there documentation on it that I missed somewhere, or a helpful youtube video?

If not, is there a way to fetch the count of unread messages for the logged in user?

First to have access to the functionality you have 2 steps.
1- enable public profiles here: /dashboard/system/registration/profiles
2- make each user edit their profile by checking the box "I would like to receive private messages

Once that’s done you should have a new item in your menu (provided your theme didn’t override it) called “members” and a sub entry called “directory”
Alternatively you can navigate to /members/directory

There you can click on any user and if they have enabled private messages in step 2 above, you can send them a message.

users can check their messages by going to their profile /members/profile, click on the “edit” button and then go to “private messages”
Alternatively they can navigate directly to /account/messages

Now to programmatically check the number of unread private messages
You will need the Mailbox class to get the user’s inbox (class concrete\src\User\PrivateMessage\Mailbox.php)

you will first use the get($user, $msgMailboxID) method where $user is an object of type Concrete\Core\User\User.
To get the logged in user you could simple do

$user = new \Concrete\Core\User\User();

And $msgMailboxID would be Mailbox::MBTYPE_INBOX

From that object you can get a list of messages using getMessageList()

This will give you an object of type PrivateMessageList (class concrete\src\User\PrivateMessage\PrivateMessageList.php)

Using this object’s get() method you’ll get an array of all the messages. Each message is an object of type privateMessage (class concrete\src\User\PrivateMessage\PrivateMessage.php)

So you loop through the array and for each message you call the method isMessageUnread() which will let you filter your list.

An example code would be

use Concrete\Core\User\PrivateMessage\Mailbox;
use Concrete\Core\User\User;

$msgMailboxID = Mailbox::MBTYPE_INBOX;
$user = new User();
$messageCount = 0;

if ($user->isRegistered()) {
    $inbox = Mailbox::get($user, $msgMailboxID);
    $messageList = $inbox->getMessageList()->get();
    if (count($messageList)) {
        foreach ($messageList as $message) {
            $messageCount += (int) $message->isMessageUnread();

$messageCount will tell you how many unread messages the user has in their inbox.

You should probably also check whether the user has enabled private messages by checking on the proper user attribute.

Hope this helps.

1 Like

Thanks for taking the time to try and help with this.
I tried your code out, but got the following error that I’m so far unable to solve;

“Object of class Concrete\Core\User\PrivateMessage\PrivateMessage could not be converted to string”

My bad. Replace this line

$messageCount += (int) $message->isMessageUnread();


if ($message->isMessageUnread()) {

Still the same error, sadly.
If I remove the if statement, the error remains, but remove the foreach and it goes away.

Managed to get it working with

foreach ($messageList as $key => $val) {
            if ($val->isMessageUnread()) {

There was a typo in my original code, a missing closing parenthesis in the first “if”. I corrected it in my original post.

With that correction, the code works as is. Doing a foreach loop the way you did wouldn’t make any difference as $val would still be the exact same object as $message in my original code.

I also tested both the original line

$messageCount += (int) $message->isMessageUnread();

and the other one

if ($message->isMessageUnread()) {

And they both work correctly.

Anyway, glad I could help :slight_smile: