[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |