From d6823704761db63bd87431c7c0e5c171d90037f2 Mon Sep 17 00:00:00 2001
From: Jared Hancock <jared@osticket.com>
Date: Tue, 12 Aug 2014 13:11:45 -0500
Subject: [PATCH] draft: Avoid ajax requests for setting up the draft

Drafts now are placed directly into the HTML response. The response contains
the draft information as well as the original content saved in the database
for the content being modified. The draft itself is placed into the redactor
box rather than the current content.

This patch also reduces some of the [Draft Saved] notices where there is no
content or the content has not yet been modified.
---
 include/class.draft.php                       |  4 ++--
 include/class.forms.php                       | 21 ++++++++++-------
 include/client/view.inc.php                   | 10 +++++---
 include/staff/cannedresponse.inc.php          | 10 ++++----
 include/staff/faq.inc.php                     |  9 ++++----
 include/staff/page.inc.php                    |  7 +++---
 .../staff/templates/ticket-status.tmpl.php    |  3 ++-
 include/staff/ticket-open.inc.php             | 21 +++++++++++------
 include/staff/ticket-view.inc.php             | 23 +++++++++++--------
 include/staff/tpl.inc.php                     |  7 +++---
 scp/emailtest.php                             |  6 +++--
 11 files changed, 75 insertions(+), 46 deletions(-)

diff --git a/include/class.draft.php b/include/class.draft.php
index a58fb52f9..d8bbbcd30 100644
--- a/include/class.draft.php
+++ b/include/class.draft.php
@@ -38,10 +38,10 @@ class Draft extends VerySimpleModel {
 
     static function getDraftAndDataAttrs($namespace, $id=0, $original='') {
         $draft_body = null;
-        $attrs = array(sprintf('data-draft-namespace="%s"', $namespace));
+        $attrs = array(sprintf('data-draft-namespace="%s"', Format::htmlchars($namespace)));
         $criteria = array('namespace'=>$namespace);
         if ($id) {
-            $attrs[] = sprintf('data-draft-object-id="%s"', $id);
+            $attrs[] = sprintf('data-draft-object-id="%s"', Format::htmlchars($id));
             $criteria['namespace'] .= '.' . $id;
         }
         if ($draft = static::lookup($criteria)) {
diff --git a/include/class.forms.php b/include/class.forms.php
index c80c34ba1..fc1519a66 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -2014,20 +2014,25 @@ class ThreadEntryWidget extends Widget {
     function render($client=null) {
         global $cfg;
 
+        $object_id = false;
+        if (!$client) {
+            $namespace = 'ticket.staff';
+        }
+        else {
+            $namespace = 'ticket.client';
+            $object_id = substr(session_id(), -12);
+        }
+        list($draft, $attrs) = Draft::getDraftAndDataAttrs($namespace, $object_id, $this->value);
         ?><div style="margin-bottom:0.5em;margin-top:0.5em"><strong><?php
         echo Format::htmlchars($this->field->get('label'));
         ?></strong>:</div>
+
         <textarea style="width:100%;" name="<?php echo $this->field->get('name'); ?>"
             placeholder="<?php echo Format::htmlchars($this->field->get('hint')); ?>"
-            <?php if (!$client) { ?>
-                data-draft-namespace="ticket.staff"
-            <?php } else { ?>
-                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 ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                ?> draft draft-delete" <?php echo $attrs; ?>
             cols="21" rows="8" style="width:80%;"><?php echo
-            Format::htmlchars($this->value); ?></textarea>
+            Format::htmlchars($draft ?: $this->value); ?></textarea>
     <?php
         $config = $this->field->getConfiguration();
         if (!$config['attachments'])
diff --git a/include/client/view.inc.php b/include/client/view.inc.php
index dc3a0419f..efebfe775 100644
--- a/include/client/view.inc.php
+++ b/include/client/view.inc.php
@@ -172,9 +172,13 @@ if (!$ticket->isClosed() || $ticket->isReopenable()) { ?>
                 <span id="msg"><em><?php echo $msg; ?> </em></span><font class="error">*&nbsp;<?php echo $errors['message']; ?></font>
                 <br/>
                 <textarea name="message" id="message" cols="50" rows="9" wrap="soft"
-                    data-draft-namespace="ticket.client"
-                    data-draft-object-id="<?php echo $ticket->getId(); ?>"
-                    class="richtext ifhtml draft"><?php echo $info['message']; ?></textarea>
+                    class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                        ?> draft" <?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('ticket.client', $ticket->getId(), $info['message']);
+    echo $attrs; ?>><?php echo $draft ?: $info['message'];
+                ?></textarea>
+            </td>
+        </tr>
         <?php
         if ($messageField->isAttachmentsEnabled()) { ?>
 <?php
diff --git a/include/staff/cannedresponse.inc.php b/include/staff/cannedresponse.inc.php
index 6be5a63b1..ad0d784fb 100644
--- a/include/staff/cannedresponse.inc.php
+++ b/include/staff/cannedresponse.inc.php
@@ -83,10 +83,12 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                     &nbsp;&nbsp;&nbsp;(<a class="tip" href="#ticket_variables"><?php echo __('Supported Variables'); ?></a>)
                     </div>
                 <textarea name="response" class="richtext draft draft-delete" cols="21" rows="12"
-                    data-draft-namespace="canned"
-                    data-draft-object-id="<?php if (isset($canned)) echo $canned->getId(); ?>"
-                    style="width:98%;" class="richtext draft"><?php
-                        echo $info['response']; ?></textarea>
+                    style="width:98%;" class="richtext draft" <?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('canned',
+        is_object($canned) ? $canned->getId() : false, $info['response']);
+    echo $attrs; ?>><?php echo $draft ?: $info['response'];
+                ?></textarea>
+                <br><br>
                 <div><h3><?php echo __('Canned Attachments'); ?> <?php echo __('(optional)'); ?>
                 &nbsp;<i class="help-tip icon-question-sign" href="#canned_attachments"></i></h3>
                 <div class="error"><?php echo $errors['files']; ?></div>
diff --git a/include/staff/faq.inc.php b/include/staff/faq.inc.php
index 4fcea8138..ee27bfab2 100644
--- a/include/staff/faq.inc.php
+++ b/include/staff/faq.inc.php
@@ -88,10 +88,11 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                     <b><?php echo __('Answer');?></b>&nbsp;<font class="error">*&nbsp;<?php echo $errors['answer']; ?></font></div>
                 </div>
                 <textarea name="answer" cols="21" rows="12"
-                    style="width:98%;" class="richtext draft"
-                    data-draft-namespace="faq"
-                    data-draft-object-id="<?php if (is_object($faq)) echo $faq->getId(); ?>"
-                    ><?php echo $info['answer']; ?></textarea>
+                    style="width:98%;" class="richtext draft" <?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('faq',
+        is_object($faq) ? $faq->getId() : false, $info['answer']);
+    echo $attrs; ?>><?php echo $draft ?: $info['answer'];
+                ?></textarea>
             </td>
         </tr>
         <tr>
diff --git a/include/staff/page.inc.php b/include/staff/page.inc.php
index 532bfc0af..49f2cbea4 100644
--- a/include/staff/page.inc.php
+++ b/include/staff/page.inc.php
@@ -105,13 +105,14 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
          <tr>
             <td colspan=2 style="padding-left:3px;">
                 <textarea name="body" cols="21" rows="12" style="width:98%;" class="richtext draft"
-                    data-draft-namespace="page" data-draft-object-id="<?php echo $info['id']; ?>"
-                    ><?php echo $info['body']; ?></textarea>
+<?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('page', $info['id'], $info['body']);
+    echo $attrs; ?>><?php echo $draft ?: $info['body']; ?></textarea>
             </td>
         </tr>
         <tr>
             <th colspan="2">
-                <em><strong><?php echo __('Internal Notes'); ?></strong>: 
+                <em><strong><?php echo __('Internal Notes'); ?></strong>:
                 <?php echo __("be liberal, they're internal"); ?></em>
             </th>
         </tr>
diff --git a/include/staff/templates/ticket-status.tmpl.php b/include/staff/templates/ticket-status.tmpl.php
index 5e0d84ae3..eae1b3272 100644
--- a/include/staff/templates/ticket-status.tmpl.php
+++ b/include/staff/templates/ticket-status.tmpl.php
@@ -84,7 +84,8 @@ $action = $info['action'] ?: ('#tickets/status/'. $state);
                         ?>
                         <textarea name="comments" id="comments"
                             cols="50" rows="3" wrap="soft" style="width:100%"
-                            class="richtext ifhtml no-bar"
+                            class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                            ?> no-bar"
                             placeholder="<?php echo $placeholder; ?>"><?php
                             echo $info['comments']; ?></textarea>
                     </td>
diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php
index 39acb0864..d70af212e 100644
--- a/include/staff/ticket-open.inc.php
+++ b/include/staff/ticket-open.inc.php
@@ -302,13 +302,17 @@ if ($_POST)
                 $signature = '';
                 if ($thisstaff->getDefaultSignatureType() == 'mine')
                     $signature = $thisstaff->getSignature(); ?>
-                <textarea class="richtext ifhtml draft draft-delete"
-                    data-draft-namespace="ticket.staff.response"
-                    data-signature="<?php
+                <textarea
+                    class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                        ?> draft draft-delete" data-signature="<?php
                         echo Format::htmlchars(Format::viewableImages($signature)); ?>"
                     data-signature-field="signature" data-dept-field="deptId"
                     placeholder="<?php echo __('Initial response for the ticket'); ?>"
                     name="response" id="response" cols="21" rows="8"
+                    style="width:80%;" <?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('ticket.staff.response', false, $info['response']);
+    echo $attrs; ?>><?php echo $draft ?: $info['response'];
+                ?></textarea>
                     style="width:80%;"><?php echo $info['response']; ?></textarea>
                     <div class="attachments">
 <?php
@@ -371,11 +375,14 @@ print $response_form->getField('attachments')->render();
         </tr>
         <tr>
             <td colspan=2>
-                <textarea class="richtext ifhtml draft draft-delete"
+                <textarea
+                    class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                        ?> draft draft-delete"
                     placeholder="<?php echo __('Optional internal note (recommended on assignment)'); ?>"
-                    data-draft-namespace="ticket.staff.note" name="note"
-                    cols="21" rows="6" style="width:80%;"
-                    ><?php echo $info['note']; ?></textarea>
+                    name="note" cols="21" rows="6" style="width:80%;" <?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('ticket.staff.note', false, $info['note']);
+    echo $attrs; ?>><?php echo $draft ?: $info['note'];
+                ?></textarea>
             </td>
         </tr>
     </tbody>
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index 078af3a0a..83f7622ed 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -561,17 +561,18 @@ $tcount+= $ticket->getNumNotes();
                     } ?>
                     <input type="hidden" name="draft_id" value=""/>
                     <textarea name="response" id="response" cols="50"
-                        data-draft-namespace="ticket.response"
                         data-signature-field="signature" data-dept-id="<?php echo $dept->getId(); ?>"
                         data-signature="<?php
                             echo Format::htmlchars(Format::viewableImages($signature)); ?>"
                         placeholder="<?php echo __(
                         'Start writing your response here. Use canned responses from the drop-down above'
                         ); ?>"
-                        data-draft-object-id="<?php echo $ticket->getId(); ?>"
                         rows="9" wrap="soft"
-                        class="richtext ifhtml draft draft-delete"><?php
-                        echo $info['response']; ?></textarea>
+                        class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                            ?> draft draft-delete" <?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('ticket.response', $ticket->getId(), $info['response']);
+    echo $attrs; ?>><?php echo $draft ?: $info['response'];
+                    ?></textarea>
                 <div id="reply_form_attachments" class="attachments">
 <?php
 print $response_form->getField('attachments')->render();
@@ -671,9 +672,11 @@ print $response_form->getField('attachments')->render();
                     <div class="error"><?php echo $errors['note']; ?></div>
                     <textarea name="note" id="internal_note" cols="80"
                         placeholder="<?php echo __('Note details'); ?>"
-                        rows="9" wrap="soft" data-draft-namespace="ticket.note"
-                        data-draft-object-id="<?php echo $ticket->getId(); ?>"
-                        class="richtext ifhtml draft draft-delete"><?php echo $info['note'];
+                        rows="9" wrap="soft"
+                        class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                            ?> draft draft-delete" <?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('ticket.note', $ticket->getId(), $info['note']);
+    echo $attrs; ?>><?php echo $draft ?: $info['note'];
                         ?></textarea>
                 <div class="attachments">
 <?php
@@ -764,7 +767,8 @@ print $note_form->getField('attachments')->render();
                 <td>
                     <textarea name="transfer_comments" id="transfer_comments"
                         placeholder="<?php echo __('Enter reasons for the transfer'); ?>"
-                        class="richtext ifhtml no-bar" cols="80" rows="7" wrap="soft"><?php
+                        class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                            ?> no-bar" cols="80" rows="7" wrap="soft"><?php
                         echo $info['transfer_comments']; ?></textarea>
                     <span class="error"><?php echo $errors['transfer_comments']; ?></span>
                 </td>
@@ -861,7 +865,8 @@ print $note_form->getField('attachments')->render();
                     <textarea name="assign_comments" id="assign_comments"
                         cols="80" rows="7" wrap="soft"
                         placeholder="<?php echo __('Enter reasons for the assignment or instructions for assignee'); ?>"
-                        class="richtext ifhtml no-bar"><?php echo $info['assign_comments']; ?></textarea>
+                        class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                            ?> no-bar"><?php echo $info['assign_comments']; ?></textarea>
                     <span class="error"><?php echo $errors['assign_comments']; ?></span><br>
                 </td>
             </tr>
diff --git a/include/staff/tpl.inc.php b/include/staff/tpl.inc.php
index fe048decd..37e29177e 100644
--- a/include/staff/tpl.inc.php
+++ b/include/staff/tpl.inc.php
@@ -108,9 +108,10 @@ $tpl=$msgtemplates[$selected];
     </div>
     <input type="hidden" name="draft_id" value=""/>
     <textarea name="body" cols="21" rows="16" style="width:98%;" wrap="soft"
-        data-toolbar-external="#toolbar"
-        class="richtext draft" data-draft-namespace="tpl.<?php echo Format::htmlchars($selected); ?>"
-        data-draft-object-id="<?php echo $tpl_id; ?>"><?php echo $info['body']; ?></textarea>
+        data-toolbar-external="#toolbar" class="richtext draft" <?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('tpl.'.$selected, $tpl_id, $info['body']);
+    echo $attrs; ?>><?php echo $draft ?: $info['body'];
+    ?></textarea>
 </div>
 
 <p style="text-align:center">
diff --git a/scp/emailtest.php b/scp/emailtest.php
index c714ef1d0..1246dff08 100644
--- a/scp/emailtest.php
+++ b/scp/emailtest.php
@@ -116,8 +116,10 @@ require(STAFFINC_DIR.'header.inc.php');
                 <div style="padding-top:0.5em;padding-bottom:0.5em">
                 <em><strong><?php echo __('Message');?></strong>: <?php echo __('email message to send.');?></em>&nbsp;<span class="error">*&nbsp;<?php echo $errors['message']; ?></span></div>
                 <textarea class="richtext draft draft-delete" name="message" cols="21"
-                    data-draft-namespace="email.diag"
-                    rows="10" style="width: 90%;"><?php echo $info['message']; ?></textarea>
+                    rows="10" style="width: 90%;" <?php
+    list($draft, $attrs) = Draft::getDraftAndDataAttrs('email.diag', false, $info['message']);
+    echo $attrs; ?>><?php echo $draft ?: $info['message'];
+                 ?></textarea>
             </td>
         </tr>
     </tbody>
-- 
GitLab