From 2e70611b80b62e8f31fe6921184e8dbda99e5f7e Mon Sep 17 00:00:00 2001
From: Peter Rotich <peter@osticket.com>
Date: Tue, 3 Nov 2015 19:20:46 +0000
Subject: [PATCH] Thread View Sort Order

Add a preference option to set the sort order of the thread entries in DESC or
ASC order.

 * System Default order is ASC
 * Auto-scroll is disabled when sort order is set to DESC.
---
 include/class.staff.php                       |  4 +++-
 include/class.thread.php                      |  3 +++
 include/staff/profile.inc.php                 | 24 ++++++++++++++++++-
 include/staff/templates/task-view.tmpl.php    |  3 ++-
 .../staff/templates/thread-entries.tmpl.php   | 17 ++++++++++---
 include/staff/ticket-view.inc.php             |  6 +++--
 6 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/include/class.staff.php b/include/class.staff.php
index 8eb4aab39..e3273fae5 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -86,7 +86,8 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
                     // Defaults
                     array(
                         'default_from_name' => '',
-                        'datetime_format' => '',
+                        'datetime_format'   => '',
+                        'thread_view_order' => '',
                         ));
             $this->_config = $_config->getInfo();
         }
@@ -675,6 +676,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
         $_config->updateAll(array(
                     'datetime_format' => $vars['datetime_format'],
                     'default_from_name' => $vars['default_from_name'],
+                    'thread_view_order' => $vars['thread_view_order'],
                     )
                 );
         $this->_config = $_config->getInfo();
diff --git a/include/class.thread.php b/include/class.thread.php
index 595b9671b..6abb8a8df 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -244,6 +244,9 @@ class Thread extends VerySimpleModel {
         if ($type && is_array($type))
             $entries->filter(array('type__in' => $type));
 
+        if ($options['sort'] && !strcasecmp($options['sort'], 'DESC'))
+            $entries->order_by('-id');
+
         // Precache all the attachments on this thread
         AttachmentFile::objects()->filter(array(
             'attachments__thread_entry__thread__id' => $this->id
diff --git a/include/staff/profile.inc.php b/include/staff/profile.inc.php
index c3fd062b8..e71a1d1e0 100644
--- a/include/staff/profile.inc.php
+++ b/include/staff/profile.inc.php
@@ -223,7 +223,29 @@ if ($avatar->isChangeable()) { ?>
                 <div class="error"><?php echo $errors['default_from_name']; ?></div>
             </td>
         </tr>
-
+        <tr>
+            <td><?php echo __('Thread View Order');?>:
+              <div class="faded"><?php echo __('The order of thread entries');?></div>
+            </td>
+            <td>
+                <select name="thread_view_order">
+                  <?php
+                   $options=array(
+                           'desc' => __('Descending'),
+                           'asc' => __('Ascending'),
+                           '' => '— '.__('System Default').' —',
+                           );
+                  foreach($options as $k=>$v) {
+                      echo sprintf('<option value="%s" %s>%s</option>',
+                                $k
+                                ,($staff->thread_view_order == $k) ? 'selected="selected"' : ''
+                                ,$v);
+                  }
+                  ?>
+                </select>
+                <div class="error"><?php echo $errors['thread_view_order']; ?></div>
+            </td>
+        </tr>
         <tr>
             <td><?php echo __('Default Signature');?>:
               <div class="faded"><?php echo __('This can be selected when replying to a thread');?></div>
diff --git a/include/staff/templates/task-view.tmpl.php b/include/staff/templates/task-view.tmpl.php
index 47acc7a7c..a2a95ff4e 100644
--- a/include/staff/templates/task-view.tmpl.php
+++ b/include/staff/templates/task-view.tmpl.php
@@ -311,7 +311,8 @@ if (!$ticket) { ?>
      $task->getThread()->render(array('M', 'R', 'N'),
              array(
                  'mode' => Thread::MODE_STAFF,
-                 'container' => 'taskThread'
+                 'container' => 'taskThread',
+                 'sort' => $thisstaff->thread_view_order
                  )
              );
      ?>
diff --git a/include/staff/templates/thread-entries.tmpl.php b/include/staff/templates/thread-entries.tmpl.php
index a3f3bdfc7..cabd7560b 100644
--- a/include/staff/templates/thread-entries.tmpl.php
+++ b/include/staff/templates/thread-entries.tmpl.php
@@ -1,5 +1,15 @@
 <?php
-$events = $events->order_by('id');
+
+$sort = 'id';
+if ($options['sort'] && !strcasecmp($options['sort'], 'DESC'))
+    $sort = '-id';
+
+$cmp = function ($a, $b) use ($sort) {
+    return ($sort == 'id')
+        ? ($a < $b) : $a > $b;
+};
+
+$events = $events->order_by($sort);
 $events = $events->getIterator();
 $events->rewind();
 $event = $events->current();
@@ -33,7 +43,7 @@ foreach (Attachment::objects()->filter(array(
             //       changes in dates between thread items.
             foreach ($entries as $entry) {
                 // Emit all events prior to this entry
-                while ($event && $event->timestamp < $entry->created) {
+                while ($event && $cmp($event->timestamp, $entry->created)) {
                     $event->render(ThreadEvent::MODE_STAFF);
                     $events->next();
                     $event = $events->current();
@@ -79,6 +89,7 @@ foreach (Attachment::objects()->filter(array(
         $('#'+container).data('imageUrls', <?php echo JsonDataEncoder::encode($urls); ?>);
         // Trigger thread processing.
         if ($.thread)
-            $.thread.onLoad(container);
+            $.thread.onLoad(container,
+                    {autoScroll: <?php echo $sort == 'id' ? 'true' : 'false'; ?>});
     });
 </script>
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index 16e22b016..ca3ba69cd 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -497,8 +497,10 @@ $tcount = $ticket->getThreadEntries($types)->count();
     $ticket->getThread()->render(
             array('M', 'R', 'N'),
             array(
-                'html-id' => 'ticketThread',
-                'mode' => Thread::MODE_STAFF)
+                'html-id'   => 'ticketThread',
+                'mode'      => Thread::MODE_STAFF,
+                'sort'      => $thisstaff->thread_view_order
+                )
             );
 ?>
 <div class="clear"></div>
-- 
GitLab