@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class AphrontStackTraceView extends AphrontView {
4
5 private $trace;
6
7 public function setTrace($trace) {
8 $this->trace = $trace;
9 return $this;
10 }
11
12 public function render() {
13 $trace = $this->trace;
14
15 $libraries = PhutilBootloader::getInstance()->getAllLibraries();
16
17 // TODO: Make this configurable?
18 $path = 'https://we.phorge.it/diffusion/%s/browse/master/src/';
19
20 $callsigns = array(
21 'arcanist' => 'ARC',
22 'phabricator' => 'P',
23 );
24
25 $rows = array();
26 $depth = count($trace);
27 foreach ($trace as $part) {
28 $lib = null;
29 $file = idx($part, 'file');
30 if ($file !== null && $file !== '') {
31 $relative = $file;
32 foreach ($libraries as $library) {
33 $root = phutil_get_library_root($library);
34 if (Filesystem::isDescendant($file, $root)) {
35 $lib = $library;
36 $relative = Filesystem::readablePath($file, $root);
37 break;
38 }
39 }
40 }
41
42 $where = '';
43 if (isset($part['class'])) {
44 $where .= $part['class'].'::';
45 }
46 if (isset($part['function'])) {
47 $where .= $part['function'].'()';
48 }
49
50 if ($file) {
51 if ($lib && isset($callsigns[$lib])) {
52 $attrs = array('title' => $file);
53 $attrs['href'] = sprintf($path, $callsigns[$lib]).
54 str_replace(DIRECTORY_SEPARATOR, '/', $relative).
55 '$'.$part['line'];
56 $attrs['target'] = '_blank';
57 $file_name = phutil_tag(
58 'a',
59 $attrs,
60 $relative);
61 } else {
62 $file_name = phutil_tag(
63 'span',
64 array(
65 'title' => $file,
66 ),
67 $relative);
68 }
69 $file_name = hsprintf('%s : %d', $file_name, $part['line']);
70 } else {
71 $file_name = phutil_tag('em', array(), '(Internal)');
72 }
73
74
75 $rows[] = array(
76 $depth--,
77 $lib,
78 $file_name,
79 $where,
80 );
81 }
82 $table = new AphrontTableView($rows);
83 $table->setHeaders(
84 array(
85 pht('Depth'),
86 pht('Library'),
87 pht('File'),
88 pht('Where'),
89 ));
90 $table->setColumnClasses(
91 array(
92 'n',
93 '',
94 '',
95 'wide',
96 ));
97
98 return phutil_tag(
99 'div',
100 array(
101 'class' => 'exception-trace',
102 ),
103 $table->render());
104 }
105
106}