Personal messages in MODx Revolution

we wanted another one service, decided to implement in MODx Revolution. The reasons for this decision, as well as the project itself lie far beyond the scope of this article, perhaps (read: definitely) I'll write about it later. Today I want to tell, how to solve a specific task.

So, you must implement the “social” element in the form of private messages users. Search ready additions for MODx nothing gave, and gugleniya on this topic. True, some glimpses of still , but clearly not in that direction. Well, did not want to use resources (which are documents) for other purposes. And then I drew attention to the fact that the MODx what is called “out of the box” is already implemented message system, with one small “but”: you can use them only in admin interface, which let users do not assumed. Even any hints on snippets to use in the frontend. It was then that I decided to dig a little deeper.

1. What has been done to us


So, what we have. The database contains a table of MODx and xPDO modx_user_messages corresponding class modUserMessage. In principle, nothing prevents us to use them for our message system, we will do that.

To access the class methods are used getObject, getCollection, newObject and others, depending on what we need to do.

Yes, and a few words about the privacy of your messages, all the same they personal and also the recipient should not be visible to anyone. So first you have to configure on our site authorization (in the MODx repository has a wonderful package, Login, and information on this topic, see easy).

UPD. Before I publish the article, as this subject today illuminated

2. Learn to read posts


Go from simple to complex. Suppose we have a system of authorization and users can register and login to the system. Okay, let's make the page inbox, which will display the incoming messages for a specific user.

Create a new resource and the assigned access rights only for registered users, to metalogenia “passers-by” did not even know about this page. Again, I will not dwell on this point, the article isn't about that.

In MODx, in any chunk, or resource available the placeholder [[+modx.user.id]], which will return the id of the current logged in user. For “passers-by” it will return ”0”. It is what we will use as the destination (if any of abrasheva knows a more reliable way to determine the current user, happy to learn from his experience).

So, in our new resource will place the snippet call, which we now write:

the
[[!msg-inbox? &userId=`[[+modx.user.id]]`]]


Please note, we pass as parameter the userId id of the current user. Now let's create a snippet with the name of the msg-inbox and add the following code:

the
<?php

$output = ";

$outputSeparator = isset($outputSeparator) ? $outputSeparator : "\n";

$userId = isset($userId) ? $userId : 0;

$limit = isset($limit) ? (integer) $limit : 10;

$offset = isset($offset) ? (integer) $offset : 0;

$tpl = isset($tpl) ? $tpl : 'inbox_tpl';

if ($userId == 0) {

return;

}

$c = $modx- > newQuery('modUserMessage');

$c- > where(array(

'recipient' = > $userId



));

$c- > sortby('date_sent','DESC');

$c->limit($offset,$limit);

$messages = $modx- > getCollection('modUserMessage',$c);

foreach ($messages as $msg){

$msgarray = $msg->toArray();

$output .= $modx- > getChunk($tpl, $msgarray) . $outputSeparator;

$msg->set('read',1);

$msg->save();

}

return $output;



As you can see, nothing particularly outstanding. Here we first accept the parameters, if any are specified, or specify their default values. Then we in any case again check the user id (if someone playful pens in the ACL climbed), if 0, stop the execution of the snippet. By the way, when you call the snippet always have to specify the userId, otherwise it defaults to the value 0 and the snippet stops at this step.

Then we prepare xPDO to the query in the database. We need messages that adresat has id equal to userId. We also share other options that we need at a page-oriented output messages — $limit and $offset. Well sorted in descending order by date. The line “$messages = $modx- > getCollection('modUserMessage',$c);” does direct sampling of modUserMessage by the criterion $c. Then go through the resulting array and use chunk instead of the template. Since the display we in fact read the message, they put a status read is set to “1”, i.e. “read”.
Now we need to create a template for displaying messages. To do this, create a new chunk with name “inbox_tpl” and add the following:

the
<div class=”inbox-message [[+read:isequalto=`0`:then=`unread`]]”>

<p><b>From:</b> [[+sender:userinfo=`username`]] </p>

<p><b>date:</b> [[+date_sent]] </p>

<p><b>Theme:</b> [[+subject]] </p>

<p><b>Message:</b>

[[+message]]</p>

</div>



In principle, the HTML markup can be absolutely any, on your taste. So I do not even point out here the styles. The only thing I would like to draw attention to is the indication of unread messages. I used the class that is assigned to a container message, if the value read is 0: class=”inbox-message[[+read:isequalto=`0`:then=` unread`]]”. Otherwise, the class unread just not added. Thus, unread messages can “highlight” using CSS. If you want, you can display the text “not read” or the corresponding icon.

Now will test. Register new user and login in the frontend. Go to the page inbox, and of course, see nothing, so no we are not yet written. Well, let's send a test message. Go to the admin menu “Users”- > “Messages”. Click “New message”, select the user, fill in the fields “Subject” and “Message” and send. Now back to the page inbox, and voila — we are new unread message from admin user!

3. Sent messages


For full communication is not enough read the messages they need to send. Well, let's add to our page a message sending form. Let's open our resource inbox and add the form:

the
<form action="[[*id]]" method="post">

<label>Who </label><input type="text" name="to" value=""/>

<label>Topic </label><input type="text" name="subj" value=""/>

<label>Message </label><textarea name="msg"></textarea> 



<input type="submit" name="send" value="Send"/>

</form>



Again, all on a primitive level. To process the form using the snippet FormIt. In my opinion, your one-stop tool for processing forms. For data processing FormIt can cause a chain of snippets — “hooks” (hooks). Hooks can perform a variety of actions — spam protection, form validation and others. If any hook rejects the form (for example, during validation), it will return false, and following it in the chain hooks will fail. Plus, you can pass error message.

To send a message, we will write your hook and feed him to the FormIt. To get started, add a resource inbox call FormIt. It is recommended to place it as high as possible on the page, we'll post it to shape and call to the snippet msg-inbox:

the
[[!FormIt? &hooks=`msg-send` &submitVar=`send`]]



Note the second parameter submitVar. In it we specify the name of the “Send” button, so FormIt will know exactly what form on the page and how to handle. Needless to say, the shapes on the page may be several.

Now create a new snippet with the name msg-send and add the following:

the
<?php

$userid = isset($userId) ? $userId: 0;

if ($userid == 0) {

return false; // Anonymus are not held

}; 

$to = $hook->getValue('to');

$message = $hook->getValue('msg');

$subj = $hook->getValue('subj');

$msg = $modx- > newObject('modUserMessage');

$msg->fromArray(array(

'sender' => $userid,

'recipient' = > $to,

'message' => $message

'subject' => $subj,

'read' => 0,

'private' => 1,

'date_sent'= > strftime('%Y-%m-%d %T'),

));

$msg->save();

return true;



Here again we first check to anonymity, then pick up the data from the form. FormIt stores them in the object $hook. You can get them using the $hook -> getValue () method, and the method of $hook -> getValues() will return an array with all the form data. Next, we create a new object modUserMessage and fill its properties with data. We also add the date of sending of the message and type — private=1.

Persistent, over. At this stage in the “to” field need to write the id of the recipient. Try to send a message to yourself. If you are logged in the frontend as admin, then beneficiary id will be equal to 1. Fill in the remaining fields and click “send”. If done correctly, a message will appear on our page. Now you can try to zaregistrirovat a few users and try to throw messages to each other.

Opinion


I deliberately did not include in the article the definition of the user name or selecting a destination from the list — it all depends on your objectives and wishes. Besides, I leave a lot of room for creativity, and to thoughtless copy-paste was smaller. And what about the user names give a hint users in MODx essentially the same objects, only their class is called modUser.

This article does not claim to be a complete solution, because there are no control messages or sorting, and other things. I just showed that to expand the functionality of MODx custom snippets is not so difficult as it seems at first glance.

Good luck!

PS Thank you-know-what!
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

March Habrameeting in Kiev

PostgreSQL load testing using JMeter, Yandex.Tank and Overload

Monitoring PostgreSQL with Zabbix