diff --git a/classes/conversation.php b/classes/conversation.php index 5f9d172..710a69a 100644 --- a/classes/conversation.php +++ b/classes/conversation.php @@ -168,6 +168,38 @@ public function close() { return true; } + /** + * Reopen + * @return bool + * @throws \coding_exception + * @throws \dml_exception + * @throws \moodle_exception + */ + public function reopen() { + global $DB, $USER; + + $context = $this->dialogue->context; + + // Is this a draft. + if (is_null($this->_conversationid)) { + throw new \moodle_exception('cannotreopendraftconversation', 'dialogue'); + } + // Permission check. + $canopen = (($this->_authorid == $USER->id) || has_capability('mod/dialogue:reopen', $context)); + if (!$canopen) { + throw new \moodle_exception('nopermissiontoreopen', 'dialogue'); + } + + $openstate = dialogue::STATE_OPEN; + $closedstate = dialogue::STATE_CLOSED; + $params = array('conversationid' => $this->conversationid, 'state' => $closedstate); + + // Reopen all messages in conversation that have a close state, we don't worry about drafts etc. + $DB->set_field('dialogue_messages', 'state', $openstate, $params); + + return true; + } + /** * Delete * @return bool diff --git a/classes/event/conversation_reopened.php b/classes/event/conversation_reopened.php new file mode 100644 index 0000000..a543b6b --- /dev/null +++ b/classes/event/conversation_reopened.php @@ -0,0 +1,71 @@ +. + +namespace mod_dialogue\event; + + +/** + * The mod_dialogue conversation reopened event. + * + * @package mod_dialogue + * @copyright Catalyst IT Ltd + * @author Sumaiya Javed <> + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class conversation_reopened extends \core\event\base { + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'u'; + $this->data['edulevel'] = self::LEVEL_OTHER; + $this->data['objecttable'] = 'dialogue_conversations'; + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The user with id '$this->userid' has reopened the conversation with " . + "id '$this->objectid' in the dialogue with the course module id '$this->contextinstanceid'."; + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventconversationreopened', 'mod_dialogue'); + } + + /** + * Get URL related to the action + * + * @return \moodle_url + */ + public function get_url() { + + $url = new \moodle_url('/mod/dialogue/conversation.php', array('conversationid' => $this->objectid, + 'id' => $this->contextinstanceid)); + + return $url; + } +} diff --git a/conversation.php b/conversation.php index a540523..4d89ea0 100644 --- a/conversation.php +++ b/conversation.php @@ -105,6 +105,28 @@ exit; } +// Reopen conversation. +if ($action == 'reopen') { + if (!empty($confirm) && confirm_sesskey()) { + $conversation->reopen(); + // Trigger conversation closed event. + $eventparams = array( + 'context' => $context, + 'objectid' => $conversation->conversationid + ); + $event = \mod_dialogue\event\conversation_reopened::create($eventparams); + $event->trigger(); + redirect($returnurl, get_string('conversationreopen', 'dialogue', + $conversation->subject)); + } + echo $OUTPUT->header($activityrecord->name); + $pageurl->param('confirm', $conversationid); + $message = get_string('conversationreopenconfirm', 'dialogue', $conversation->subject); + echo $OUTPUT->confirm($message, $pageurl, $returnurl); + echo $OUTPUT->footer(); + exit; +} + // Close conversation. if ($action == 'close') { if (!empty($confirm) && confirm_sesskey()) { diff --git a/db/access.php b/db/access.php index bcef09f..141da80 100755 --- a/db/access.php +++ b/db/access.php @@ -127,6 +127,30 @@ ) ), + 'mod/dialogue:reopen' => array( + + 'captype' => 'read', + 'contextlevel' => CONTEXT_MODULE, + 'archetypes' => array( + 'student' => CAP_PREVENT, + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_PREVENT + ) + ), + + 'mod/dialogue:reopenany' => array( + + 'captype' => 'read', + 'contextlevel' => CONTEXT_MODULE, + 'archetypes' => array( + 'student' => CAP_PREVENT, + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_PREVENT + ) + ), + 'mod/dialogue:receive' => array( 'captype' => 'read', diff --git a/lang/en/dialogue.php b/lang/en/dialogue.php index abb155d..26799e7 100644 --- a/lang/en/dialogue.php +++ b/lang/en/dialogue.php @@ -35,6 +35,7 @@ $string['cachedef_unreadcounts'] = 'Users unread message counts in conversations'; $string['cachedef_userdetails'] = 'User brief details, all enrolled users'; $string['cannotclosedraftconversation'] = 'You cannot close a conversation that hasn\'t started!'; +$string['cannotreopendraftconversation'] = 'You reopen a conversation that hasn\'t started!'; $string['cannotdeleteopenconversation'] = 'You cannot delete a open conversation'; $string['closeconversation'] = 'Close conversation'; $string['closed'] = 'Closed'; @@ -49,6 +50,8 @@ $string['conversationclosed'] = 'Conversation {$a} has been closed'; $string['conversationdeleteconfirm'] = 'Are you sure you want to delete conversation {$a}, this cannot be undone?'; $string['conversationdeleted'] = 'Conversation {$a} has been deleted'; +$string['conversationreopenconfirm'] = 'Are you sure you want to reopen conversation {$a} ?'; +$string['conversationreopened'] = 'Conversation {$a} has been reopened'; $string['conversationdiscarded'] = 'Conversation discarded'; $string['conversationlistdisplayheader'] = 'Displaying {$a->show} {$a->state} conversations {$a->groupname}'; $string['conversationopened'] = 'Conversation has been opened'; @@ -65,6 +68,7 @@ $string['deletealldrafts'] = 'Delete all drafts'; $string['deleteallrules'] = 'Delete all opener rules'; $string['deleteconversation'] = 'Delete conversation'; +$string['reopenconversation'] = 'Reopen conversation'; $string['deletereply'] = 'Delete reply'; $string['dialogue:addinstance'] = 'Add a Dialogue'; $string['dialogue:bulkopenrulecreate'] = 'Create a bulk opener rule'; @@ -74,6 +78,8 @@ $string['dialogue:delete'] = 'Delete own'; $string['dialogue:deleteany'] = 'Delete any'; $string['dialogue:open'] = 'Open a conversation'; +$string['dialogue:reopen'] = 'Reopen own'; +$string['dialogue:reopenany'] = 'Reopen any'; $string['dialogue:receive'] = 'Receive, who can be the recipient when opening a conversation'; $string['dialogue:reply'] = 'Reply'; $string['dialogue:replyany'] = 'Reply any'; @@ -100,6 +106,7 @@ $string['eventconversationcreated'] = 'Conversation created'; $string['eventconversationdeleted'] = 'Conversation deleted'; $string['eventconversationviewed'] = 'Conversation viewed'; +$string['conversationreopen'] = 'Conversation reopened'; $string['eventreplycreated'] = 'Reply created'; $string['everybody'] = 'Everybody (free for all)'; $string['everyone'] = 'Everyone'; @@ -143,6 +150,7 @@ $string['nodraftsfound'] = 'No drafts found!'; $string['nomatchingpeople'] = 'No people match \'{$a}\''; $string['nopermissiontoclose'] = 'You do not have permission to close this conversation!'; +$string['nopermissiontoreopen'] = 'You do not have permission to reopen this conversation!'; $string['nopermissiontodelete'] = 'You do not have permission to delete!'; $string['nosubject'] = '[no subject]'; $string['numberattachments'] = '{$a} attachments'; diff --git a/renderer.php b/renderer.php index ee418cd..6864aa6 100644 --- a/renderer.php +++ b/renderer.php @@ -101,6 +101,22 @@ public function render_conversation(mod_dialogue\conversation $conversation) { } } + if ($conversation->state == \mod_dialogue\dialogue::STATE_CLOSED) { + $canreopen = ((has_capability('mod/dialogue:reopen', $context) && $USER->id == $conversation->author->id) || + has_capability('mod/dialogue:reopenany', $context)); + + if ($canreopen) { + $html .= html_writer::start_tag('li'); + $trashicon = html_writer::tag('i', '', array('class' => "fa fa-trash-o")); + $reopenurl = new moodle_url('/mod/dialogue/conversation.php'); + $reopenurl->param('id', $cm->id); + $reopenurl->param('conversationid', $conversation->conversationid); + $reopenurl->param('action', 'reopen'); + $html .= html_writer::link($reopenurl, get_string('reopenconversation', 'dialogue') . $trashicon); + $html .= html_writer::end_tag('li'); + } + } + $candelete = ((has_capability('mod/dialogue:delete', $context) && $USER->id == $conversation->author->id) || has_capability('mod/dialogue:deleteany', $context)); diff --git a/version.php b/version.php index d069e32..063cade 100644 --- a/version.php +++ b/version.php @@ -23,8 +23,8 @@ */ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2024050200; -$plugin->release = 2024050200; +$plugin->version = 2024100901; +$plugin->release = 2024100901; $plugin->requires = 2022112805; // Requires 4.1 or higher. $plugin->component = 'mod_dialogue'; // Full name of the plugin (used for diagnostics). $plugin->maturity = MATURITY_STABLE; // This version's maturity level.