📜 ⬆️ ⬇️

Personal messages in MODx Revolution

My friend and I thought of one service, we decided to implement it on the MODx Revolution. The reasons for this decision, as well as the project itself lie far beyond the scope of this article, perhaps (read necessarily) I will write about it later. Today I want to tell how a specific problem was solved.

So, it is necessary to implement the “social” element in the form of personal messages of users. Searches for ready-made add-ons for MODx did not give anything sensible, just like googling on this topic. True, there were some glimpses after all , but clearly not in that direction. Well, I didn’t want to use resources (which are documents) for other purposes. And here I drew attention to the fact that in MODx itself, what is called “out of the box”, a message system is already implemented, with one small “but”: you can only use them in the admin area, where users are not supposed to start up at all. Not even a hint of snippets for use in the frontend. It was then that I decided to dig deeper.

1. What has been done to us


So what we have. The MODx database contains the modx_user_messages table and the corresponding xPDO class modUserMessage. In principle, nothing prevents us from using them for our message system, which we will do.

To access the class, getObject, getCollection, newObject, and others are used, depending on what we need to do.
')
Yes, and a few words about the privacy of messages, yet they are personal and should not be visible to anyone except the addressee. Therefore, you will first have to configure authorization on our site (there is a wonderful Login package in the MODx repository, and it is easy to find information on this topic).

UPD. I did not have time to publish the article, as this topic today highlighted

2. Learning to read messages


Let's go from simple to complex. Suppose we have an authorization system and users can register and log in to the system. Well, let's make an inbox page where incoming messages for a specific user will be displayed.

We create a new resource and assign it access rights only for registered users, so that unauthorized “passers-by” do not even suspect about this page. Again, I will not dwell on this point in detail, because the article is not about that.

In MODx, a placeholder [[+ modx.user.id]] is available in any chunk or resource, which will return the id of the currently logged in user. For “passers-by,” he will return “0”. We will use it as an addressee (if someone from the community knows a more reliable way to determine the current user, we will gladly pass on his experience).

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

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


Note that we pass the current userId id of the current user. Now create a snippet called msg-inbox and add the following code to it:

 <?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, or specify their default values. Then, just in case, we once again check the user id (all of a sudden, someone got up with playful pens in the ACL), if 0, stop the snippet. By the way, when calling a snippet, you always need to specify userId, otherwise it defaults to 0 and the snippet stops working at this step.

Next, we prepare xPDO to query in the database. We need messages for which the URL has an id equal to userId. We also pass other parameters that we will need for paginated output of messages - $ limit and $ offset. Well, sort in descending order of date. The string “$ messages = $ modx-> getCollection ('modUserMessage', $ c);” directly selects from modUserMessage by the criterion $ c. Then we go through the resulting array and use the chunk instead of the template. Since, when displaying, we essentially read the messages, set them to read status equal to “1”, i.e. “Read”.

Now you need to create a template for displaying messages. To do this, create a new chunk with the name “inbox_tpl” and add the following to it:

 <div class=”inbox-message [[+read:isequalto=`0`:then=`unread`]]”> <p><b>:</b> [[+sender:userinfo=`username`]] </p> <p><b>:</b> [[+date_sent]] </p> <p><b>:</b> [[+subject]] </p> <p><b>:</b> [[+message]]</p> </div> 


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

Now we will test. We register a new user and log in to the frontend. We go to the inbox page, and naturally, we do not see anything, since no one has yet written to us. Well, let's send a test message. Go to admin area, menu “Users” -> “Messages”. Click the “New message” button, select the user, fill in the “Subject” and “Messages” fields and send. Now let's go back to the inbox page, and voila - we have a new unread message from the admin user!

3. We send messages


For full communication is not enough to read messages, they need to somehow send. Well, add to our page a form to send a message. Open our inbox resource and add the form:

 <form action="[[*id]]" method="post"> <label> </label><input type="text" name="to" value=""/> <label> </label><input type="text" name="subj" value=""/> <label> </label><textarea name="msg"></textarea> <input type="submit" name="send" value=""/> </form> 


Again, everything is on a primitive level. We will process the form using the FormIt snippet. In my opinion, the most convenient form processing tool. For data processing, FormIt can call a chain of snippets - “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 the following hooks in the chain will not be executed. Plus, you can send an error message.

To send a message, we will write our hook and feed it with a FormIt. To begin with, let's add a FormIt call to the inbox resource. It is recommended to place it as high as possible on the page, that is, we will place it before the form and call the msg-inbox snippet:

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


Pay attention to 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 process. Needless to say, there may be several forms on the page.

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

 <?php $userid = isset($userId) ? $userId: 0; if ($userid == 0) { return false; //    }; $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 for anonymity, then collect data from the form. FormIt stores them in the $ hook object. You can get them using the $ hook method -> getValue (), and the $ hook method -> getValues ​​() returns an array with all the form data. Next, we create a new modUserMessage object and populate its properties with data. We also add the date the message was sent and the type is private = 1.

Save, go check. At this stage, in the “To” field you need to write the recipient's id. Let's try to send a message to yourself. If you are logged in as an admin in the front-end, the recipient's id will be 1. Fill in the remaining fields and click “send”. If everything is done correctly, our message will appear on our own page. Now you can try to register several users and try to throw messages to each other.

Conclusion


I intentionally did not include in the article the definition of a user by name or the choice of a recipient from the list - it all depends directly on your tasks and wishes. In addition, I leave you a lot of room for creativity, and that the thoughtless copy-paste was smaller. And about user names I give a hint - users in MODx are essentially the same objects, only their class is called modUser.

This article does not claim to be a complete solution, because there is no message management, no sorting, and so on. I just showed that expanding the functionality of MODx with custom snippets is not so difficult as it seems at first glance.

Good luck!

PS Thank you know for what!

Source: https://habr.com/ru/post/132802/


All Articles