[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/chatlog/controller/ -> PhabricatorChatLogChannelLogController.php (source)

   1  <?php
   2  
   3  final class PhabricatorChatLogChannelLogController
   4    extends PhabricatorChatLogController {
   5  
   6    private $channelID;
   7  
   8    public function shouldAllowPublic() {
   9      return true;
  10    }
  11  
  12    public function willProcessRequest(array $data) {
  13      $this->channelID = $data['channelID'];
  14    }
  15  
  16    public function processRequest() {
  17      $request = $this->getRequest();
  18      $user = $request->getUser();
  19  
  20      $uri = clone $request->getRequestURI();
  21      $uri->setQueryParams(array());
  22  
  23      $pager = new AphrontCursorPagerView();
  24      $pager->setURI($uri);
  25      $pager->setPageSize(250);
  26  
  27      $query = id(new PhabricatorChatLogQuery())
  28        ->setViewer($user)
  29        ->withChannelIDs(array($this->channelID));
  30  
  31      $channel = id(new PhabricatorChatLogChannelQuery())
  32                ->setViewer($user)
  33                ->withIDs(array($this->channelID))
  34                ->executeOne();
  35  
  36      if (!$channel) {
  37        return new Aphront404Response();
  38      }
  39  
  40      list($after, $before, $map) = $this->getPagingParameters($request, $query);
  41  
  42      $pager->setAfterID($after);
  43      $pager->setBeforeID($before);
  44  
  45      $logs = $query->executeWithCursorPager($pager);
  46  
  47      // Show chat logs oldest-first.
  48      $logs = array_reverse($logs);
  49  
  50  
  51      // Divide all the logs into blocks, where a block is the same author saying
  52      // several things in a row. A block ends when another user speaks, or when
  53      // two minutes pass without the author speaking.
  54  
  55      $blocks = array();
  56      $block = null;
  57  
  58      $last_author = null;
  59      $last_epoch = null;
  60      foreach ($logs as $log) {
  61        $this_author = $log->getAuthor();
  62        $this_epoch  = $log->getEpoch();
  63  
  64        // Decide whether we should start a new block or not.
  65        $new_block = ($this_author !== $last_author) ||
  66                     ($this_epoch - (60 * 2) > $last_epoch);
  67  
  68        if ($new_block) {
  69          if ($block) {
  70            $blocks[] = $block;
  71          }
  72          $block = array(
  73            'id'      => $log->getID(),
  74            'epoch'   => $this_epoch,
  75            'author'  => $this_author,
  76            'logs'    => array($log),
  77          );
  78        } else {
  79          $block['logs'][] = $log;
  80        }
  81  
  82        $last_author = $this_author;
  83        $last_epoch = $this_epoch;
  84      }
  85      if ($block) {
  86        $blocks[] = $block;
  87      }
  88  
  89      // Figure out CSS classes for the blocks. We alternate colors between
  90      // lines, and highlight the entire block which contains the target ID or
  91      // date, if applicable.
  92  
  93      foreach ($blocks as $key => $block) {
  94        $classes = array();
  95        if ($key % 2) {
  96          $classes[] = 'alternate';
  97        }
  98        $ids = mpull($block['logs'], 'getID', 'getID');
  99        if (array_intersect_key($ids, $map)) {
 100          $classes[] = 'highlight';
 101        }
 102        $blocks[$key]['class'] = $classes ? implode(' ', $classes) : null;
 103      }
 104  
 105  
 106      require_celerity_resource('phabricator-chatlog-css');
 107  
 108      $out = array();
 109      foreach ($blocks as $block) {
 110        $author = $block['author'];
 111        $author = id(new PhutilUTF8StringTruncator())
 112          ->setMaximumGlyphs(18)
 113          ->truncateString($author);
 114        $author = phutil_tag('td', array('class' => 'author'), $author);
 115  
 116        $href = $uri->alter('at', $block['id']);
 117        $timestamp = $block['epoch'];
 118        $timestamp = phabricator_datetime($timestamp, $user);
 119        $timestamp = phutil_tag(
 120          'a',
 121            array(
 122              'href' => $href,
 123              'class' => 'timestamp',
 124            ),
 125          $timestamp);
 126  
 127        $message = mpull($block['logs'], 'getMessage');
 128        $message = implode("\n", $message);
 129        $message = phutil_tag(
 130          'td',
 131            array(
 132              'class' => 'message',
 133            ),
 134            array(
 135              $timestamp,
 136              $message,
 137            ));
 138  
 139        $out[] = phutil_tag(
 140          'tr',
 141          array(
 142            'class' => $block['class'],
 143          ),
 144          array(
 145            $author,
 146            $message,
 147          ));
 148      }
 149  
 150      $links = array();
 151  
 152      $first_uri = $pager->getFirstPageURI();
 153      if ($first_uri) {
 154        $links[] = phutil_tag(
 155          'a',
 156          array(
 157            'href' => $first_uri,
 158          ),
 159          "\xC2\xAB ".pht('Newest'));
 160      }
 161  
 162      $prev_uri = $pager->getPrevPageURI();
 163      if ($prev_uri) {
 164        $links[] = phutil_tag(
 165          'a',
 166          array(
 167            'href' => $prev_uri,
 168          ),
 169          "\xE2\x80\xB9 ".pht('Newer'));
 170      }
 171  
 172      $next_uri = $pager->getNextPageURI();
 173      if ($next_uri) {
 174        $links[] = phutil_tag(
 175          'a',
 176          array(
 177            'href' => $next_uri,
 178          ),
 179          pht('Older')." \xE2\x80\xBA");
 180      }
 181  
 182      $pager_top = phutil_tag(
 183        'div',
 184        array('class' => 'phabricator-chat-log-pager-top'),
 185        $links);
 186  
 187      $pager_bottom = phutil_tag(
 188        'div',
 189        array('class' => 'phabricator-chat-log-pager-bottom'),
 190        $links);
 191  
 192      $crumbs = $this
 193        ->buildApplicationCrumbs()
 194        ->addTextCrumb($channel->getChannelName(), $uri);
 195  
 196      $form = id(new AphrontFormView())
 197        ->setUser($user)
 198        ->setMethod('GET')
 199        ->setAction($uri)
 200        ->appendChild(
 201          id(new AphrontFormTextControl())
 202            ->setLabel(pht('Date'))
 203            ->setName('date')
 204            ->setValue($request->getStr('date')))
 205        ->appendChild(
 206          id(new AphrontFormSubmitControl())
 207            ->setValue(pht('Jump')));
 208  
 209      $filter = new AphrontListFilterView();
 210      $filter->appendChild($form);
 211  
 212      $table = phutil_tag(
 213        'table',
 214          array(
 215            'class' => 'phabricator-chat-log',
 216          ),
 217        $out);
 218  
 219      $log = phutil_tag(
 220        'div',
 221          array(
 222            'class' => 'phabricator-chat-log-panel',
 223          ),
 224          $table);
 225  
 226      $jump_link = phutil_tag(
 227        'a',
 228          array(
 229            'href' => '#latest',
 230          ),
 231          pht('Jump to Bottom')." \xE2\x96\xBE");
 232  
 233      $jump = phutil_tag(
 234        'div',
 235          array(
 236            'class' => 'phabricator-chat-log-jump',
 237          ),
 238          $jump_link);
 239  
 240      $jump_target = phutil_tag(
 241        'div',
 242          array(
 243            'id' => 'latest',
 244          ));
 245  
 246      $content = phutil_tag(
 247        'div',
 248          array(
 249            'class' => 'phabricator-chat-log-wrap',
 250          ),
 251          array(
 252            $jump,
 253            $pager_top,
 254            $log,
 255            $jump_target,
 256            $pager_bottom,
 257          ));
 258  
 259      return $this->buildApplicationPage(
 260        array(
 261          $crumbs,
 262          $filter,
 263          $content,
 264        ),
 265        array(
 266          'title' => pht('Channel Log'),
 267        ));
 268    }
 269  
 270    /**
 271     * From request parameters, figure out where we should jump to in the log.
 272     * We jump to either a date or log ID, but load a few lines of context before
 273     * it so the user can see the nearby conversation.
 274     */
 275    private function getPagingParameters(
 276      AphrontRequest $request,
 277      PhabricatorChatLogQuery $query) {
 278  
 279      $user = $request->getUser();
 280  
 281      $at_id = $request->getInt('at');
 282      $at_date = $request->getStr('date');
 283  
 284      $context_log = null;
 285      $map = array();
 286  
 287      $query = clone $query;
 288      $query->setLimit(8);
 289  
 290      if ($at_id) {
 291        // Jump to the log in question, and load a few lines of context before
 292        // it.
 293        $context_logs = $query
 294          ->setAfterID($at_id)
 295          ->execute();
 296  
 297        $context_log = last($context_logs);
 298  
 299        $map = array(
 300          $at_id => true,
 301        );
 302  
 303      } else if ($at_date) {
 304        $timestamp = PhabricatorTime::parseLocalTime($at_date, $user);
 305  
 306        if ($timestamp) {
 307          $context_logs = $query
 308            ->withMaximumEpoch($timestamp)
 309            ->execute();
 310  
 311          $context_log = last($context_logs);
 312  
 313          $target_log = head($context_logs);
 314          if ($target_log) {
 315            $map = array(
 316              $target_log->getID() => true,
 317            );
 318          }
 319        }
 320      }
 321  
 322      if ($context_log) {
 323        $after = null;
 324        $before = $context_log->getID() - 1;
 325      } else {
 326        $after = $request->getInt('after');
 327        $before = $request->getInt('before');
 328      }
 329  
 330      return array($after, $before, $map);
 331    }
 332  
 333  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1