Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / people / controller / PhabricatorPeopleProfileViewController.php
blobb929d980d5c8a15d60c0ad58323afb6224900caa
1 <?php
3 final class PhabricatorPeopleProfileViewController
4 extends PhabricatorPeopleProfileController {
6 public function shouldAllowPublic() {
7 return true;
10 public function handleRequest(AphrontRequest $request) {
11 $viewer = $this->getViewer();
12 $username = $request->getURIData('username');
14 $user = id(new PhabricatorPeopleQuery())
15 ->setViewer($viewer)
16 ->withUsernames(array($username))
17 ->needProfileImage(true)
18 ->needAvailability(true)
19 ->executeOne();
20 if (!$user) {
21 return new Aphront404Response();
24 $this->setUser($user);
25 $header = $this->buildProfileHeader();
27 $properties = $this->buildPropertyView($user);
28 $name = $user->getUsername();
30 $feed = $this->buildPeopleFeed($user, $viewer);
32 $view_all = id(new PHUIButtonView())
33 ->setTag('a')
34 ->setIcon(
35 id(new PHUIIconView())
36 ->setIcon('fa-list-ul'))
37 ->setText(pht('View All'))
38 ->setHref('/feed/?userPHIDs='.$user->getPHID());
40 $feed_header = id(new PHUIHeaderView())
41 ->setHeader(pht('Recent Activity'))
42 ->addActionLink($view_all);
44 $feed = id(new PHUIObjectBoxView())
45 ->setHeader($feed_header)
46 ->addClass('project-view-feed')
47 ->appendChild($feed);
49 $projects = $this->buildProjectsView($user);
50 $calendar = $this->buildCalendarDayView($user);
52 $home = id(new PHUITwoColumnView())
53 ->setHeader($header)
54 ->addClass('project-view-home')
55 ->addClass('project-view-people-home')
56 ->setMainColumn(
57 array(
58 $properties,
59 $feed,
61 ->setSideColumn(
62 array(
63 $projects,
64 $calendar,
65 ));
67 $navigation = $this->newNavigation(
68 $user,
69 PhabricatorPeopleProfileMenuEngine::ITEM_PROFILE);
71 $crumbs = $this->buildApplicationCrumbs();
72 $crumbs->setBorder(true);
74 return $this->newPage()
75 ->setTitle($user->getUsername())
76 ->setNavigation($navigation)
77 ->setCrumbs($crumbs)
78 ->setPageObjectPHIDs(
79 array(
80 $user->getPHID(),
82 ->appendChild(
83 array(
84 $home,
85 ));
88 private function buildPropertyView(
89 PhabricatorUser $user) {
91 $viewer = $this->getRequest()->getUser();
92 $view = id(new PHUIPropertyListView())
93 ->setUser($viewer)
94 ->setObject($user);
96 $field_list = PhabricatorCustomField::getObjectFields(
97 $user,
98 PhabricatorCustomField::ROLE_VIEW);
99 $field_list->appendFieldsToPropertyList($user, $viewer, $view);
101 if (!$view->hasAnyProperties()) {
102 return null;
105 $header = id(new PHUIHeaderView())
106 ->setHeader(pht('User Details'));
108 $view = id(new PHUIObjectBoxView())
109 ->appendChild($view)
110 ->setHeader($header)
111 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
112 ->addClass('project-view-properties');
114 return $view;
117 private function buildProjectsView(
118 PhabricatorUser $user) {
120 $viewer = $this->getViewer();
121 $projects = id(new PhabricatorProjectQuery())
122 ->setViewer($viewer)
123 ->withMemberPHIDs(array($user->getPHID()))
124 ->needImages(true)
125 ->withStatuses(
126 array(
127 PhabricatorProjectStatus::STATUS_ACTIVE,
129 ->execute();
131 $header = id(new PHUIHeaderView())
132 ->setHeader(pht('Projects'));
134 if (!empty($projects)) {
135 $limit = 5;
136 $render_phids = array_slice($projects, 0, $limit);
137 $list = id(new PhabricatorProjectListView())
138 ->setUser($viewer)
139 ->setProjects($render_phids);
141 if (count($projects) > $limit) {
142 $header_text = pht(
143 'Projects (%s)',
144 phutil_count($projects));
146 $header = id(new PHUIHeaderView())
147 ->setHeader($header_text)
148 ->addActionLink(
149 id(new PHUIButtonView())
150 ->setTag('a')
151 ->setIcon('fa-list-ul')
152 ->setText(pht('View All'))
153 ->setHref('/project/?member='.$user->getPHID()));
157 } else {
158 $list = id(new PHUIInfoView())
159 ->setSeverity(PHUIInfoView::SEVERITY_NODATA)
160 ->appendChild(pht('User does not belong to any projects.'));
163 $box = id(new PHUIObjectBoxView())
164 ->setHeader($header)
165 ->appendChild($list)
166 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
168 return $box;
171 private function buildCalendarDayView(PhabricatorUser $user) {
172 $viewer = $this->getViewer();
173 $class = 'PhabricatorCalendarApplication';
175 if (!PhabricatorApplication::isClassInstalledForViewer($class, $viewer)) {
176 return null;
179 // Don't show calendar information for disabled users, since it's probably
180 // not useful or accurate and may be misleading.
181 if ($user->getIsDisabled()) {
182 return null;
185 $midnight = PhabricatorTime::getTodayMidnightDateTime($viewer);
186 $week_end = clone $midnight;
187 $week_end = $week_end->modify('+3 days');
189 $range_start = $midnight->format('U');
190 $range_end = $week_end->format('U');
192 $events = id(new PhabricatorCalendarEventQuery())
193 ->setViewer($viewer)
194 ->withDateRange($range_start, $range_end)
195 ->withInvitedPHIDs(array($user->getPHID()))
196 ->withIsCancelled(false)
197 ->needRSVPs(array($viewer->getPHID()))
198 ->execute();
200 $event_views = array();
201 foreach ($events as $event) {
202 $viewer_is_invited = $event->isRSVPInvited($viewer->getPHID());
204 $can_edit = PhabricatorPolicyFilter::hasCapability(
205 $viewer,
206 $event,
207 PhabricatorPolicyCapability::CAN_EDIT);
209 $epoch_min = $event->getStartDateTimeEpoch();
210 $epoch_max = $event->getEndDateTimeEpoch();
212 $event_view = id(new AphrontCalendarEventView())
213 ->setCanEdit($can_edit)
214 ->setEventID($event->getID())
215 ->setEpochRange($epoch_min, $epoch_max)
216 ->setIsAllDay($event->getIsAllDay())
217 ->setIcon($event->getIcon())
218 ->setViewerIsInvited($viewer_is_invited)
219 ->setName($event->getName())
220 ->setDatetimeSummary($event->renderEventDate($viewer, true))
221 ->setURI($event->getURI());
223 $event_views[] = $event_view;
226 $event_views = msort($event_views, 'getEpochStart');
228 $day_view = id(new PHUICalendarWeekView())
229 ->setViewer($viewer)
230 ->setView('week')
231 ->setEvents($event_views)
232 ->setWeekLength(3)
233 ->render();
235 $header = id(new PHUIHeaderView())
236 ->setHeader(pht('Calendar'))
237 ->setHref(
238 urisprintf(
239 '/calendar/?invited=%s#R',
240 $user->getUsername()));
242 $box = id(new PHUIObjectBoxView())
243 ->setHeader($header)
244 ->appendChild($day_view)
245 ->addClass('calendar-profile-box')
246 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
248 return $box;
251 private function buildPeopleFeed(
252 PhabricatorUser $user,
253 $viewer) {
255 $query = id(new PhabricatorFeedQuery())
256 ->setViewer($viewer)
257 ->withFilterPHIDs(array($user->getPHID()))
258 ->setLimit(100)
259 ->setReturnPartialResultsOnOverheat(true);
261 $stories = $query->execute();
263 $overheated_view = null;
264 $is_overheated = $query->getIsOverheated();
265 if ($is_overheated) {
266 $overheated_message =
267 PhabricatorApplicationSearchController::newOverheatedError(
268 (bool)$stories);
270 $overheated_view = id(new PHUIInfoView())
271 ->setSeverity(PHUIInfoView::SEVERITY_WARNING)
272 ->setTitle(pht('Query Overheated'))
273 ->setErrors(
274 array(
275 $overheated_message,
279 $builder = new PhabricatorFeedBuilder($stories);
280 $builder->setUser($viewer);
281 $builder->setShowHovercards(true);
282 $builder->setNoDataString(pht('To begin on such a grand journey, '.
283 'requires but just a single step.'));
284 $view = $builder->buildView();
286 return array(
287 $overheated_view,
288 $view->render(),