From d136963b74d456877cb9e8ed82d8b24b6cbca2d8 Mon Sep 17 00:00:00 2001 From: Peter Rotich <peter@osticket.com> Date: Mon, 16 Nov 2015 07:45:48 +0000 Subject: [PATCH] Textarea input cleanup Let textarea widgets parse and clean input based on configured text format. Add cleanup routine to ThreadEntryBody Clean response/note inputs --- include/class.forms.php | 42 +++++++++++++++++++++++++++++++++++++--- include/class.thread.php | 21 ++++++++++++++++++-- include/class.ticket.php | 3 ++- scp/tickets.php | 11 +++++------ tickets.php | 9 +++++---- 5 files changed, 70 insertions(+), 16 deletions(-) diff --git a/include/class.forms.php b/include/class.forms.php index 7e092ad9a..6f6d3b409 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -1995,6 +1995,13 @@ class ThreadEntryField extends FormField { return $media; } + function getConfiguration() { + global $cfg; + $config = parent::getConfiguration(); + $config['html'] = (bool) $cfg->isRichTextEnabled(); + return $config; + } + function getConfigurationOptions() { global $cfg; @@ -3112,6 +3119,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 { @@ -3533,8 +3555,8 @@ class SectionBreakWidget extends Widget { class ThreadEntryWidget extends Widget { function render($options=array()) { - global $cfg; + $config = $this->field->getConfiguration(); $object_id = false; if ($options['client']) { $namespace = $options['draft-namespace'] @@ -3548,12 +3570,11 @@ class ThreadEntryWidget extends Widget { ?> <textarea style="width:100%;" name="<?php echo $this->field->get('name'); ?>" placeholder="<?php echo Format::htmlchars($this->field->get('placeholder')); ?>" - class="<?php if ($cfg->isRichTextEnabled()) echo 'richtext'; + class="<?php if ($config['html']) echo 'richtext'; ?> draft draft-delete" <?php echo $attrs; ?> cols="21" rows="8" style="width:80%;"><?php echo Format::htmlchars($this->value) ?: $draft; ?></textarea> <?php - $config = $this->field->getConfiguration(); if (!$config['attachments']) return; @@ -3577,6 +3598,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 7b5b94418..fb3e03acd 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -2132,6 +2132,22 @@ class ThreadEntryBody /* extends SplString */ { return new ThreadEntryBody($text); } } + + static function clean($text, $format=null) { + global $cfg; + + if (!$format && $cfg) + $format = $cfg->isRichTextEnabled() ? 'html' : 'text'; + + switch ($format) { + case 'html': + return trim($text, " <>br/\t\n\r") ? $text : ''; + case 'text': + return trim($text) ? $text : ''; + default: + return $text; + } + } } class TextThreadEntryBody extends ThreadEntryBody { @@ -2140,7 +2156,8 @@ class TextThreadEntryBody extends ThreadEntryBody { } function getClean() { - return Format::stripEmptyLines($this->body); + return Format::stripEmptyLines( + self::clean($this->body, $this->format)); } function prepend($what) { @@ -2187,7 +2204,7 @@ class HtmlThreadEntryBody extends ThreadEntryBody { } function getClean() { - return trim($this->body, " <>br/\t\n\r") ? Format::sanitize($this->body) : ''; + return Format::sanitize(self::clean($this->body, $this->format)); } function getSearchable() { diff --git a/include/class.ticket.php b/include/class.ticket.php index 3fe355de2..42d920f68 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -3420,7 +3420,8 @@ implements RestrictedAccess, Threadable { } // TODO: Deny action based on selected department. - + $vars['response'] = ThreadEntryBody::clean($vars['response']); + $vars['note'] = ThreadEntryBody::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 b8fc7ae44..fd07aeba5 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -82,8 +82,10 @@ if($_POST && !$errors): $errors['err'] = __('Action denied. Contact admin for access'); } else { - - if(!$_POST['response']) + $vars = $_POST; + $vars['cannedattachments'] = $response_form->getField('attachments')->getClean(); + $vars['response'] = ThreadEntryBody::clean($vars['response']); + if(!$vars['response']) $errors['response']=__('Response required'); if ($cfg->getLockTime()) { @@ -107,10 +109,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'), @@ -143,6 +141,7 @@ if($_POST && !$errors): $attachments = $note_form->getField('attachments')->getClean(); $vars['cannedattachments'] = array_merge( $vars['cannedattachments'] ?: array(), $attachments); + $vars['note'] = ThreadEntryBody::clean($vars['note']); if ($cfg->getLockTime()) { if (!$lock) { diff --git a/tickets.php b/tickets.php index 2c80ec91a..1887ae500 100644 --- a/tickets.php +++ b/tickets.php @@ -71,16 +71,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'] = ThredEntryBody::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']; -- GitLab