Totara comments
What are Totara comments?
Totara comments is a new plugin introduced in Totara 13. This plugin is used with the Weka editor to allow users to comment and reply to other users' comments on your site. This is a standalone plugin and can easily be used by other plugins.
How Totara comments work
The Totara comments plugin has its own graphQL queries and comment helper class which provides CRUD functions. For capabilities, the Totara comments plugin introduces a new approach (Interactor) to do the capability check and Interactor will return to Vue template along with comments.Â
The diagram below shows how the plugin works.
Here we use comment loader to load records from the database and map records into the comment model. In other words, the comment model is like a wrapper class of comment entity.
Main API classes and methods
Namespaces and classes
Class | Purpose |
---|---|
totara_comment\entity\comment | Stores comment record. |
totara_comment\event | Comment events and lets other plugins observe the events. |
totara_comment\formatter | Formats the comment/reply content. |
totara_comment\interactor | Checks the actor's capability. |
totara_comment\loader\comment_loader | Loads comment records from DB and map into comment models. It works as data provider, in other words, if front-end needs to render comments into page, we call loader to help web API to load the data and return data to Web API through the comment modal. |
totara_comment\pagination | Implements comment pagination . |
totara_comment\userdata | Purge and export comment that related to the user. |
totara_comment\watcher | Watches hooks from other plugins. |
totara_comment\webapi\resolver\mutation totara_comment\webapi\resolver\query totara_comment\webapi\resolver\type | Web API to provide the interface to front-end. |
Totara comments have the following structure:
Name | Type | Note | PK | FK |
---|---|---|---|---|
id | INT | Comment ID. | true | |
userid | INT | The user who clicked like on a component. | ||
area | CHAR(20) | The area name. | ||
component | CHAR(20) | The component name. | ||
instanceid | INT | The component's instance ID. | ||
parentid | INT | Remember comment ID for reply. | ||
timecreated | INT | Timestamp. | ||
format | INT | Format content. | ||
content | TEXT | User's comment. | ||
timemodified | INT | Timestamp. | ||
timedeleted | INT | Timestamp. | ||
reasondeleted | INTÂ | Reason why the comment was deleted. |
How to add comments to a component
To use Totara comments, the developer needs to create a specific folder and files under your component /totata_comment/comment_resolver
.
// example your comment +-- classes | +-- totara_comment | +-- comment_resolver.php
Enable weka_editor:
// under db direotory, create editor_weka.php $editor = [ 'comment' => [ 'showtoolbar' => false, 'includeextensions' => [ '\editor_weka\extension\hashtag', '\editor_weka\extension\mention' ] ] ];
Clarify area for weka_editor:
<Weka :id="id" component="totara_playlist" area="content" :doc="content.doc" :placeholder="$str('description', 'engage_article')" @update="handleUpdate" />
Add dependence into version.php:
$plugin->dependencies = [ 'totara_comment' => 2019101500, 'editor_weka' => 2019111800, ];
Triggering and observing event (optional)
While it is not necessary to use comment events for this, it is considered good practice to trigger an event to observe it for processing because it is facilitates decoupling and predictability of code.
To do it, make sure that event exists (the developer can check totara_comment\classes\event
).
$observers = [ //... [ 'eventname' => \totara_comment\event\comment_created::class, 'callback' => [\engage_article\observer\comment_observer::class, 'on_comment_created'] ], [ 'eventname' => \totara_comment\event\reply_created::class, 'callback' => [\engage_article\observer\comment_observer::class, 'on_reply_created'] ], [ 'eventname' => \totara_comment\event\comment_updated::class, 'callback' => [\engage_article\observer\comment_observer::class, 'on_comment_updated'] ] //... ];
Event handler in the callback:
final class comment_observer { //... public static function on_comment_created(comment_created $event): void { $record = $event->get_record_snapshot(comment::get_entity_table(), $event->objectid); $comment = comment::from_record($record); static::handle_comment($comment); } public static function on_comment_updated(comment_updated $event): void { $record = $event->get_record_snapshot(comment::get_entity_table(), $event->objectid); $comment = comment::from_record($record); static::handle_comment($comment); } //... }
Best practices
Components do not need to handle comment graphQL queries and mutation, all of them will be handled in the totara_comment, the components just need to make comment_resolver based on the component requirement for comment and for decoupling, the components only need to event handler in the callback to satisfy their need.Â