2012-02-17 19:21:38 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright 2012 Facebook, Inc.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
final class PhabricatorChatLogChannelLogController
|
|
|
|
extends PhabricatorChatLogController {
|
|
|
|
|
|
|
|
private $channel;
|
|
|
|
|
|
|
|
public function willProcessRequest(array $data) {
|
|
|
|
$this->channel = $data['channel'];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function processRequest() {
|
2012-06-02 23:00:08 +02:00
|
|
|
$request = $this->getRequest();
|
|
|
|
$user = $request->getUser();
|
|
|
|
|
|
|
|
$uri = clone $request->getRequestURI();
|
|
|
|
$uri->setQueryParams(array());
|
|
|
|
|
|
|
|
$pager = new AphrontIDPagerView();
|
|
|
|
$pager->setURI($uri);
|
|
|
|
$pager->setPageSize(250);
|
|
|
|
|
|
|
|
$query = id(new PhabricatorChatLogQuery())
|
|
|
|
->setViewer($user)
|
|
|
|
->withChannels(array($this->channel));
|
|
|
|
|
|
|
|
|
|
|
|
list($after, $before, $map) = $this->getPagingParameters($request, $query);
|
|
|
|
|
|
|
|
$pager->setAfterID($after);
|
|
|
|
$pager->setBeforeID($before);
|
2012-02-17 19:21:38 +01:00
|
|
|
|
2012-03-28 01:53:47 +02:00
|
|
|
$logs = $query->executeWithPager($pager);
|
2012-02-17 19:21:38 +01:00
|
|
|
|
2012-06-02 23:00:08 +02:00
|
|
|
// Show chat logs oldest-first.
|
|
|
|
$logs = array_reverse($logs);
|
2012-02-17 19:21:38 +01:00
|
|
|
|
|
|
|
|
2012-06-02 23:00:08 +02:00
|
|
|
// Divide all the logs into blocks, where a block is the same author saying
|
|
|
|
// several things in a row. A block ends when another user speaks, or when
|
|
|
|
// two minutes pass without the author speaking.
|
2012-02-17 19:21:38 +01:00
|
|
|
|
2012-06-02 23:00:08 +02:00
|
|
|
$blocks = array();
|
|
|
|
$block = null;
|
|
|
|
|
|
|
|
$last_author = null;
|
|
|
|
$last_epoch = null;
|
2012-02-17 19:21:38 +01:00
|
|
|
foreach ($logs as $log) {
|
|
|
|
$this_author = $log->getAuthor();
|
|
|
|
$this_epoch = $log->getEpoch();
|
|
|
|
|
2012-06-02 23:00:08 +02:00
|
|
|
// Decide whether we should start a new block or not.
|
|
|
|
$new_block = ($this_author !== $last_author) ||
|
|
|
|
($this_epoch - (60 * 2) > $last_epoch);
|
|
|
|
|
|
|
|
if ($new_block) {
|
|
|
|
if ($block) {
|
|
|
|
$blocks[] = $block;
|
|
|
|
}
|
|
|
|
$block = array(
|
|
|
|
'id' => $log->getID(),
|
|
|
|
'epoch' => $this_epoch,
|
|
|
|
'author' => $this_author,
|
|
|
|
'logs' => array($log),
|
|
|
|
);
|
2012-02-17 19:21:38 +01:00
|
|
|
} else {
|
2012-06-02 23:00:08 +02:00
|
|
|
$block['logs'][] = $log;
|
2012-02-17 19:21:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$last_author = $this_author;
|
2012-06-02 23:00:08 +02:00
|
|
|
$last_epoch = $this_epoch;
|
|
|
|
}
|
|
|
|
if ($block) {
|
|
|
|
$blocks[] = $block;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Figure out CSS classes for the blocks. We alternate colors between
|
|
|
|
// lines, and highlight the entire block which contains the target ID or
|
|
|
|
// date, if applicable.
|
|
|
|
|
|
|
|
foreach ($blocks as $key => $block) {
|
|
|
|
$classes = array();
|
|
|
|
if ($key % 2) {
|
|
|
|
$classes[] = 'alternate';
|
|
|
|
}
|
|
|
|
$ids = mpull($block['logs'], 'getID', 'getID');
|
|
|
|
if (array_intersect_key($ids, $map)) {
|
|
|
|
$classes[] = 'highlight';
|
|
|
|
}
|
|
|
|
$blocks[$key]['class'] = $classes ? implode(' ', $classes) : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
require_celerity_resource('phabricator-chatlog-css');
|
|
|
|
|
|
|
|
$out = array();
|
|
|
|
$out[] = '<table class="phabricator-chat-log">';
|
|
|
|
foreach ($blocks as $block) {
|
|
|
|
$author = $block['author'];
|
|
|
|
$author = phutil_utf8_shorten($author, 18);
|
|
|
|
$author = phutil_escape_html($author);
|
|
|
|
$author = phutil_render_tag('td', array('class' => 'author'), $author);
|
|
|
|
|
|
|
|
$message = mpull($block['logs'], 'getMessage');
|
|
|
|
$message = implode("\n", $message);
|
|
|
|
$message = phutil_escape_html($message);
|
|
|
|
$message = phutil_render_tag('td', array('class' => 'message'), $message);
|
|
|
|
|
|
|
|
$href = $uri->alter('at', $block['id']);
|
|
|
|
$timestamp = $block['epoch'];
|
|
|
|
$timestamp = phabricator_datetime($timestamp, $user);
|
|
|
|
$timestamp = phutil_render_tag('a', array('href' => $href), $timestamp);
|
|
|
|
$timestamp = phutil_render_tag(
|
|
|
|
'td',
|
|
|
|
array(
|
|
|
|
'class' => 'timestamp',
|
|
|
|
),
|
|
|
|
$timestamp);
|
|
|
|
|
|
|
|
$out[] = phutil_render_tag(
|
|
|
|
'tr',
|
|
|
|
array(
|
|
|
|
'class' => $block['class'],
|
|
|
|
),
|
|
|
|
$author.$message.$timestamp);
|
2012-02-17 19:21:38 +01:00
|
|
|
}
|
|
|
|
$out[] = '</table>';
|
|
|
|
|
2012-06-02 23:00:08 +02:00
|
|
|
$form = id(new AphrontFormView())
|
|
|
|
->setUser($user)
|
|
|
|
->setMethod('GET')
|
|
|
|
->setAction($uri)
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTextControl())
|
|
|
|
->setLabel('Date')
|
|
|
|
->setName('date')
|
|
|
|
->setValue($request->getStr('date')))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
|
|
|
->setValue('Jump'));
|
|
|
|
|
2012-02-17 19:21:38 +01:00
|
|
|
|
|
|
|
return $this->buildStandardPageResponse(
|
2012-03-28 01:53:47 +02:00
|
|
|
array(
|
2012-06-02 23:00:08 +02:00
|
|
|
'<div class="phabricator-chat-log-panel">',
|
|
|
|
$form,
|
|
|
|
'<br />',
|
2012-03-28 01:53:47 +02:00
|
|
|
implode("\n", $out),
|
2012-06-02 23:00:08 +02:00
|
|
|
$pager,
|
|
|
|
'</div>',
|
2012-03-28 01:53:47 +02:00
|
|
|
),
|
2012-02-17 19:21:38 +01:00
|
|
|
array(
|
|
|
|
'title' => 'Channel Log',
|
|
|
|
));
|
|
|
|
}
|
2012-06-02 23:00:08 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* From request parameters, figure out where we should jump to in the log.
|
|
|
|
* We jump to either a date or log ID, but load a few lines of context before
|
|
|
|
* it so the user can see the nearby conversation.
|
|
|
|
*/
|
|
|
|
private function getPagingParameters(
|
|
|
|
AphrontRequest $request,
|
|
|
|
PhabricatorChatLogQuery $query) {
|
|
|
|
|
|
|
|
$user = $request->getUser();
|
|
|
|
|
|
|
|
$at_id = $request->getInt('at');
|
|
|
|
$at_date = $request->getStr('date');
|
|
|
|
|
|
|
|
$context_log = null;
|
|
|
|
$map = array();
|
|
|
|
|
|
|
|
$query = clone $query;
|
|
|
|
$query->setLimit(8);
|
|
|
|
|
|
|
|
if ($at_id) {
|
|
|
|
// Jump to the log in question, and load a few lines of context before
|
|
|
|
// it.
|
|
|
|
$context_logs = $query
|
|
|
|
->setAfterID($at_id)
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$context_log = last($context_logs);
|
|
|
|
|
|
|
|
$map = array(
|
|
|
|
$at_id => true,
|
|
|
|
);
|
|
|
|
|
|
|
|
} else if ($at_date) {
|
|
|
|
$timezone = new DateTimeZone($user->getTimezoneIdentifier());
|
|
|
|
try {
|
|
|
|
$date = new DateTime($at_date, $timezone);
|
|
|
|
$timestamp = $date->format('U');
|
|
|
|
} catch (Exception $e) {
|
|
|
|
$timestamp = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($timestamp) {
|
|
|
|
$context_logs = $query
|
|
|
|
->withMaximumEpoch($timestamp)
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$context_log = last($context_logs);
|
|
|
|
|
|
|
|
$target_log = head($context_logs);
|
|
|
|
if ($target_log) {
|
|
|
|
$map = array(
|
|
|
|
$target_log->getID() => true,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($context_log) {
|
|
|
|
$after = null;
|
|
|
|
$before = $context_log->getID() - 1;
|
|
|
|
} else {
|
|
|
|
$after = $request->getInt('after');
|
|
|
|
$before = $request->getInt('before');
|
|
|
|
}
|
|
|
|
|
|
|
|
return array($after, $before, $map);
|
|
|
|
}
|
|
|
|
|
2012-02-17 19:21:38 +01:00
|
|
|
}
|