diff --git a/include/class.forms.php b/include/class.forms.php index 770736e84355c8432d84c7e69aa1cc8d14b7c0ab..b2c1aed1cad67777e2970a4fdf66d430d95005b5 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -1153,6 +1153,13 @@ class ThreadEntryField extends FormField { return false; } + function getConfiguration() { + global $cfg; + $config = parent::getConfiguration(); + $config['html'] = (bool) ($cfg && $cfg->isHtmlThreadEnabled()); + return $config; + } + function getConfigurationOptions() { global $cfg; @@ -1829,6 +1836,21 @@ class TextareaWidget extends Widget { </span> <?php } + + function parseValue() { + parent::parseValue(); + if (isset($this->value)) { + $value = $this->value; + $config = $this->field->getConfiguration(); + // Trim empty spaces based on text input type. + // Preserve original input if not empty. + if ($config['html']) + $this->value = trim($value, " <>br/\t\n\r") ? $value : ''; + else + $this->value = trim($value) ? $value : ''; + } + } + } class PhoneNumberWidget extends Widget { @@ -2085,8 +2107,8 @@ class SectionBreakWidget extends Widget { class ThreadEntryWidget extends Widget { function render($client=null) { - global $cfg; + $config = $this->field->getConfiguration(); ?><div style="margin-bottom:0.5em;margin-top:0.5em"><strong><?php echo Format::htmlchars($this->field->get('label')); ?></strong>:</div> @@ -2098,11 +2120,10 @@ class ThreadEntryWidget extends Widget { data-draft-namespace="ticket.client" data-draft-object-id="<?php echo substr(session_id(), -12); ?>" <?php } ?> - class="richtext draft draft-delete ifhtml" + class="<?php if ($config['html']) echo 'richtext'; ?> draft draft-delete ifhtml" cols="21" rows="8" style="width:80%;"><?php echo Format::htmlchars($this->value); ?></textarea> <?php - $config = $this->field->getConfiguration(); if (!$config['attachments']) return; @@ -2126,6 +2147,21 @@ class ThreadEntryWidget extends Widget { $field->setForm($this->field->getForm()); return $field; } + + function parseValue() { + parent::parseValue(); + if (isset($this->value)) { + $value = $this->value; + $config = $this->field->getConfiguration(); + // Trim spaces based on text input type. + // Preserve original input if not empty. + if ($config['html']) + $this->value = trim($value, " <>br/\t\n\r") ? $value : ''; + else + $this->value = trim($value) ? $value : ''; + } + } + } class FileUploadWidget extends Widget { diff --git a/include/class.thread.php b/include/class.thread.php index c13014848800056842f7ab7f7df41bcb82c8e345..9f38f47f4f177d1ba3178ddc54fbb39cb2312da8 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -1434,7 +1434,14 @@ class ThreadBody /* extends SplString */ { } function getClean() { - return trim($this->body); + switch ($this->type) { + case 'html': + return trim($this->body, " <>br/\t\n\r") ? $this->body: ''; + case 'text': + return trim($this->body) ? $this->body: ''; + default: + return trim($this->body); + } } function __toString() { @@ -1476,6 +1483,13 @@ class ThreadBody /* extends SplString */ { return new ThreadBody($text); } } + + static function clean($text, $format=null) { + global $cfg; + $format = $format ?: ($cfg->isHtmlThreadEnabled() ? 'html' : 'text'); + $body = static::fromFormattedText($text, $format); + return $body->getClean(); + } } class TextThreadBody extends ThreadBody { @@ -1484,7 +1498,7 @@ class TextThreadBody extends ThreadBody { } function getClean() { - return Format::stripEmptyLines($this->body); + return Format::stripEmptyLines(parent::getClean()); } function display($output=false) { @@ -1527,7 +1541,7 @@ class HtmlThreadBody extends ThreadBody { } function getClean() { - return trim($this->body, " <>br/\t\n\r") ? Format::sanitize($this->body) : ''; + return Format::sanitize(parent::getClean()); } function getSearchable() { diff --git a/include/class.ticket.php b/include/class.ticket.php index e64c38f40a34cc8ec1a6962db411fc4126bc2ad2..1b4c2badf0737366918a18c23524daf4d6452b98 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -888,7 +888,7 @@ class Ticket { $thisstaff ?: 'SYSTEM'); $alert = false; - if ($comments) { + if (($comments = ThreadBody::clean($comments))) { $note .= sprintf('<hr>%s', $comments); // Send out alerts if comments are included $alert = true; @@ -2179,6 +2179,8 @@ class Ticket { if(!$cfg || !$thisstaff || !$thisstaff->canEditTickets()) return false; + $vars['note'] = ThreadBody::clean($vars['note']); + $fields=array(); $fields['topicId'] = array('type'=>'int', 'required'=>1, 'error'=>__('Help topic selection is required')); $fields['slaId'] = array('type'=>'int', 'required'=>0, 'error'=>__('Select a valid SLA')); @@ -2917,6 +2919,8 @@ class Ticket { if (!$thisstaff->canAssignTickets()) unset($vars['assignId']); + $vars['response'] = ThreadBody::clean($vars['response']); + $vars['note'] = ThreadBody::clean($vars['note']); $create_vars = $vars; $tform = TicketForm::objects()->one()->getForm($create_vars); $create_vars['cannedattachments'] diff --git a/scp/tickets.php b/scp/tickets.php index a6dd4ce8b003d51047f1bf2843a442ce49d39b46..004dcc9ec97d86fb0d8337d4e2a27f5f625cb220 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -68,8 +68,10 @@ if($_POST && !$errors): if(!$thisstaff->canPostReply()) $errors['err'] = __('Action denied. Contact admin for access'); else { - - if(!$_POST['response']) + $vars = $_POST; + $vars['cannedattachments'] = $response_form->getField('attachments')->getClean(); + $vars['response'] = ThreadBody::clean($vars['response']); + if(!$vars['response']) $errors['response']=__('Response required'); //Use locks to avoid double replies if($lock && $lock->getStaffId()!=$thisstaff->getId()) @@ -80,10 +82,6 @@ if($_POST && !$errors): $errors['err']=__('Email is in banlist. Must be removed to reply.'); } - //If no error...do the do. - $vars = $_POST; - $vars['cannedattachments'] = $response_form->getField('attachments')->getClean(); - if(!$errors && ($response=$ticket->postReply($vars, $errors, $_POST['emailreply']))) { $msg = sprintf(__('%s: Reply posted successfully'), sprintf(__('Ticket #%s'), @@ -200,6 +198,7 @@ if($_POST && !$errors): $attachments = $note_form->getField('attachments')->getClean(); $vars['cannedattachments'] = array_merge( $vars['cannedattachments'] ?: array(), $attachments); + $vars['note'] = ThreadBody::clean($vars['note']); $wasOpen = ($ticket->isOpen()); if(($note=$ticket->postNote($vars, $errors, $thisstaff))) { diff --git a/tickets.php b/tickets.php index c65e9b6fd92601612a54631692fa60858312e4c2..752a2416a8edfbb23a032de5f19bd1398781df93 100644 --- a/tickets.php +++ b/tickets.php @@ -69,16 +69,17 @@ if($_POST && is_object($ticket) && $ticket->getId()): if(!$ticket->checkUserAccess($thisclient)) //double check perm again! $errors['err']=__('Access Denied. Possibly invalid ticket ID'); - if(!$_POST['message']) - - $errors['message']=__('Message required'); + $_POST['message'] = ThreadBody::clean($_POST['message']); + if (!$_POST['message']) + $errors['message'] = __('Message required'); if(!$errors) { //Everything checked out...do the magic. $vars = array( 'userId' => $thisclient->getId(), 'poster' => (string) $thisclient->getName(), - 'message' => $_POST['message']); + 'message' => $_POST['message'] + ); $vars['cannedattachments'] = $attachments->getClean(); if (isset($_POST['draft_id'])) $vars['draft_id'] = $_POST['draft_id'];