Page MenuHomec4science

PhabricatorC4sHome.php
No OneTemporary

File Metadata

Created
Wed, Nov 27, 17:26

PhabricatorC4sHome.php

<?php
final class PhabricatorC4sHome
extends PhabricatorProfileMenuItem {
const MENUITEMKEY = 'home.c4science';
public function getMenuItemTypeName() {
return pht('C4science Homepage');
}
private function getDefaultName() {
return pht('c4science');
}
public function getDisplayName(
PhabricatorProfileMenuItemConfiguration $config) {
return $this->getDefaultName();
}
public function canMakeDefault(
PhabricatorProfileMenuItemConfiguration $config) {
return true;
}
protected function newNavigationMenuItems(
PhabricatorProfileMenuItemConfiguration $config) {
$viewer = $this->getViewer();
$name = 'Home';
$icon = 'fa-home';
$href = '/home';
$item = $this->newItem()
->setHref($href)
->setName($name)
->setIcon($icon);
return array(
$item,
);
}
public function newPageContent(
PhabricatorProfileMenuItemConfiguration $config) {
$request = $this->getEngine()->getController()->getRequest();
$viewer = $this->getViewer();
if(!$viewer->getUsername()) {
$view = $this->publicPage($request, $viewer);
} else {
$view = $this->userPage($request, $viewer);
}
return $view;
}
private function userPage($request, $viewer) {
$tab_key = $request->getStr('tab');
$order_key = $request->getStr('order', 'committed');
// Get and check order key
$repo_order = id(new PhabricatorRepositoryQuery())
->getBuiltinOrders();
unset($repo_order['callsign']); //FIXME: for some reason, ordering with
// the calllsign field doesn't work
// and crashes, not very usefull though
if(!in_array($order_key, array_keys($repo_order))) {
$order_key = 'committed';
}
// My repo tab (can_edit + created)
$view_my = $this->buildRepositoryPanel(
$request, 'my', null, 10, false, $order_key, 'author');
$tab_my = id(new PHUITabView())
->setName(pht('Your repositories'))
->setKey('my')
->appendChild($view_my);
// Contribution tab (can_push)
$view_contrib = $this->buildRepositoryPanel(
$request, 'contrib', null, 10, false, $order_key, 'contrib');
$tab_contrib = id(new PHUITabView())
->setName(pht('Contribution'))
->setKey('contrib')
->appendChild($view_contrib);
// Tab Repositories
$tab_group_repo = id(new PHUITabGroupView())
->addTab($tab_my)
->addTab($tab_contrib);
if(in_array($tab_key, array('my', 'contrib'))) {
$tab_group_repo->selectTab($tab_key);
}
// Box header
$actions = id(new PhabricatorActionListView())
->setViewer($viewer);
foreach($repo_order as $orderKey => $orderValue) {
$action = id(new PhabricatorActionView())
->setName($orderValue['name'])
->setHref('?order=' . $orderKey . '#box_repo');
if($order_key == $orderKey) {
$action->setSelected(true);
}
$actions->addAction($action);
}
$order_link = id(new PHUIButtonView())
->setText('Order By: ' . $order_key)
->setTag('a')
->setIcon('fa-sort')
->setDropdown(true)
->setDropdownMenu($actions);
$header = id(new PHUIHeaderView())
->setHeader(pht('Repositories'))
->addActionLink($order_link);
// Box
$anchor = id(new PhabricatorAnchorView())
->setAnchorName('box_repo');
$tab_repo = id(new PHUIObjectBoxView())
->setHeader($header)
->setAnchor($anchor)
->addTabGroup($tab_group_repo);
// Projects member
$view_member = $this->buildProjectsPanel($request, 'member', 'member');
$tab_member = id(new PHUITabView())
->setName(pht('Member'))
->setKey('member')
->appendChild($view_member);
// Projects watcher
$view_watcher = $this->buildProjectsPanel($request, 'watcher', 'watcher');
$tab_watcher = id(new PHUITabView())
->setName(pht('Watcher'))
->setKey('watcher')
->appendChild($view_watcher);
// Tab Projects
$tab_group_proj = id(new PHUITabGroupView())
->addTab($tab_member)
->addTab($tab_watcher);
if(in_array($tab_key, array('member', 'watcher'))) {
$tab_group_proj->selectTab($tab_key);
}
$anchor = id(new PhabricatorAnchorView())
->setAnchorName('box_proj');
$tab_proj = id(new PHUIObjectBoxView())
->setHeaderText('Projects')
->setAnchor($anchor)
->addTabGroup($tab_group_proj);
// Columns
$col_repo = phutil_tag(
'div',
array(
'class' => 'homepage-panel',
),
array(
$tab_repo,
$tab_proj,
));
$col_feed = phutil_tag(
'div',
array(
'class' => 'homepage-panel',
),
array(
//$this->buildShortcuts(),
$this->buildAnnouncement(),
$this->buildFeedPanel(false),
));
$view = id(new AphrontMultiColumnView())
->addColumn($col_repo)
->addColumn($col_feed)
->setFluidLayout(true);
return $view;
}
private function publicPage($request, $viewer) {
$col_feed = phutil_tag(
'div',
array(
'class' => 'homepage-panel',
),
array(
$this->buildAnnouncement(),
$this->buildFeedPanel(),
));
$view_active = $this->buildRepositoryPanel($request, 'active', null, 10);
$tab_active = id(new PHUITabView())
->setName(pht('Recently Active'))
->setKey('active')
->appendChild($view_active);
$view_commits = $this->buildRepositoryPanel($request, 'commits', null, 10, true, 'size');
$tab_commits = id(new PHUITabView())
->setName(pht('Most commits'))
->setKey('commits')
->appendChild($view_commits);
$view_users = $this->buildRepositoryPanel($request, 'users', null, 10, true, 'users');
$tab_users = id(new PHUITabView())
->setName(pht('Most contributors'))
->setKey('users')
->appendChild($view_users);
$tab_group = id(new PHUITabGroupView())
->addTab($tab_active)
->addTab($tab_commits)
->addTab($tab_users);
$tab_key = $request->getStr('tab');
if(in_array($tab_key, array('my', 'contrib'))) {
$tab_group->selectTab($tab_key);
}
$anchor = id(new PhabricatorAnchorView())
->setAnchorName('box_repo');
$tab_view = id(new PHUIObjectBoxView())
->setHeaderText('Repositories')
->setAnchor($anchor)
->addTabGroup($tab_group);
$col_repo = phutil_tag(
'div',
array(
'class' => 'homepage-panel',
),
array(
$this->buildPresentationPanel(),
$tab_view,
));
$view = id(new AphrontMultiColumnView())
->addColumn($col_repo)
->addColumn($col_feed)
->setFluidLayout(true);
return $view;
}
private function buildAnnouncement() {
$viewer = $this->getViewer();
$dashboard = id(new PhabricatorDashboard())
->loadOneWhere('name = "Service Announcement" && editPolicy = "admin"');
if(!$dashboard) {
return;
}
$dashboard = id(new PhabricatorDashboardQuery())
->setViewer($viewer)
->withPHIDs(array($dashboard->getPHID()))
->needPanels(true)
->executeOne();
if(!$dashboard->getPanelPHIDs()) {
return;
}
$panels = id(new PhabricatorDashboardPanelQuery())
->setViewer($viewer)
->withPHIDs($dashboard->getPanelPHIDs())
->execute();
$boxes = array();
foreach($panels as $panel) {
if($panel->getPanelType() != 'text') {
continue;
}
$remarkup = new PHUIRemarkupView($viewer, $panel->getProperty('text'));
$layout = id(new PHUIBoxView())
->appendChild($remarkup)
->addMargin(PHUI::MARGIN_MEDIUM);
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText($panel->getName())
->appendChild($layout);
}
return $boxes;
}
private function buildShortcuts() {
$icons = array(
id(new PHUIIconView())
->setIcon('fa-briefcase')
->setBackground('bg-grey')
->setTooltip('Create Project')
->addClass('mmr')
->setHref('/project/edit/form/default/'),
id(new PHUIIconView())
->setIcon('fa-code')
->setBackground('bg-grey')
->setTooltip('Create Repository')
->addClass('mmr')
->setHref('/diffusion/edit/form/default/'),
id(new PHUIIconView())
->setIcon('fa-bug')
->setBackground('bg-grey')
->setTooltip('Report a bug')
->addClass('mmr')
->setHref('/maniphest/task/edit/form/8/'),
id(new PHUIIconView())
->setIcon('fa-book')
->setBackground('bg-grey')
->setTooltip('Documentation')
->addClass('mmr')
->setHref('/w/c4science')
);
$layout = id(new PHUIBoxView())
->appendChild($icons)
->addMargin(PHUI::MARGIN_MEDIUM);
$box = id(new PHUIObjectBoxView())
->setHeaderText('Shortcuts')
->appendChild($layout);
return $box;
}
private function buildFeedPanel($global=true) {
$panel_id = celerity_generate_unique_node_id();
Javelin::initBehavior(
'dashboard-async-panel',
array(
'panelID' => $panel_id,
'parentPanelPHIDs' => array(),
'headerMode' => 'none',
'dashboardID' => $global,
'uri' => '/render/feed',
));
$view_all = id(new PHUIButtonView())
->setTag('a')
->setIcon(id(new PHUIIconView())->setIcon('fa-list-ul'))
->setText(pht('View All'))
->setHref('/feed/');
$header = id(new PHUIHeaderView())
->setHeader(pht('Recent Activity'))
->addActionLink($view_all);
$feed_box = id(new PHUIBoxView())
->setID($panel_id)
->addPadding(PHUI::PADDING_LARGE)
->appendChild(pht('Loading...'));
$feed = id(new PHUIObjectBoxView())
->setHeader($header)
->appendChild($feed_box);
return $feed;
}
private function buildProjectsPanel(
$request,
$tab_key,
$filter='member',
$proj_count=10
) {
$viewer = $this->getViewer();
$pager = id(new AphrontCursorPagerView())
->setURI(new PhutilURI('?tab=' . $tab_key . '#box_proj'))
->setPageSize($proj_count);
if($tab_key == $request->getStr('tab') &&
in_array($tab_key, array('member', 'watcher'))) {
$pager
->setAfterID($request->getStr('after'))
->setBeforeID($request->getStr('before'));
}
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->setOrder('newest')
->needImages(true)
->withStatuses(array(PhabricatorProjectStatus::STATUS_ACTIVE));
if($filter == 'member') {
$projects->withMemberPHIDs(array($viewer->getPHID()));
} else if($filter == 'watcher') {
$projects->withWatcherPHIDs(array($viewer->getPHID()));
}
$projects = $projects->executeWithCursorPager($pager);
if (!empty($projects)) {
$list = id(new PhabricatorProjectListView())
->setUser($viewer)
->setProjects($projects);
} else {
if($filter == 'member') {
$str = 'No project found. [[/project/edit/form/default/ | Create a new project]].';
} else if($filter == 'watcher') {
$str = 'No project found. [[/project/query/active/ | Watch a project]].';
}
$remarkup = new PHUIRemarkupView($viewer, $str);
$list = id(new PHUIBoxView())
->addPadding(PHUI::PADDING_LARGE)
->appendChild($remarkup);
}
$box = id(new PHUIObjectBoxView())
->appendChild($list);
if($pager->willShowPagingControls()) {
$box->appendChild($pager);
}
return $box;
}
private function buildRepositoryPanel(
$request,
$tab_key,
$title,
$repo_count=5,
$compact=false,
$order='committed',
$filter=null)
{
$viewer = $this->getViewer();
$pager = id(new AphrontCursorPagerView())
->setURI(new PhutilURI('?tab=' . $tab_key . '&order=' . $order . '#box_repo'))
->setPageSize($repo_count);
if($tab_key == $request->getStr('tab') &&
in_array($tab_key, array('my', 'contrib'))) {
$pager
->setAfterID($request->getStr('after'))
->setBeforeID($request->getStr('before'));
}
// Get repositories
if($order == 'users') {
$table = id(new PhabricatorRepositoryCommit());
$repo = queryfx_all(
$table->establishConnection('r'),
'SELECT a.name, a.rid, count(*) AS cnt, a.phid FROM
(SELECT r.phid as phid, r.name AS name, repositoryID AS rid, authorPHID AS aid
FROM repository_commit JOIN repository AS r ON r.id=repositoryID
WHERE viewPolicy="public" AND authorPHID IS NOT NULL AND importStatus=15
GROUP BY aid)a GROUP BY a.rid ORDER BY cnt DESC LIMIT %d',
$repo_count);
} else {
$repo = id(new PhabricatorRepositoryQuery())
->setViewer($viewer)
->setOrder($order)
->needCommitCounts(true);
if(!$compact) {
$repo
->needMostRecentCommits(true)
->needProjectPHIDs(true)
->needProfileImage(true);
}
$capabilities = array(PhabricatorPolicyCapability::CAN_VIEW);
if($filter == 'contrib') {
$capabilities += array_fuse(array(DiffusionPushCapability::CAPABILITY));
$repo->withCanPush();
}
$repo->requireCapabilities($capabilities);
//if(in_array($filter, array('author', 'contrib'))) {
// $repo->withCanView();
//}
if(in_array($tab_key, array('active', 'commits'))) {
$repo->withCanViewPublic();
}
if($filter == 'author') {
$repo->withAuthors(array($viewer->getPHID()));
} else if($viewer->getUsername()) {
$repo->withoutAuthors(array($viewer->getPHID()));
}
$repo = $repo->executeWithCursorPager($pager);
}
// Create List
if(!empty($repo)) {
$list = new PHUIObjectItemListView();
} else {
$remarkup = new PHUIRemarkupView($viewer,
'No repository found. [[/diffusion/edit/form/default/ | Create a new repository]].');
$list = id(new PHUIBoxView())
->addPadding(PHUI::PADDING_LARGE)
->appendChild($remarkup);
}
foreach($repo as $r){
$item = id(new PHUIObjectItemView());
if($order == 'users') {
$item
->setHeader($r['name'])
->addIcon('', pht('%s Users', new PhutilNumber($r['cnt'])))
->setHref(pht('/diffusion/%d/', $r['rid']));
} else {
if($r->getStatus() == PhabricatorRepository::STATUS_INACTIVE) {
$item->setDisabled(true);
}
$item
->setHeader($r->getName())
->addIcon('', pht('%s Commit(s)', new PhutilNumber($r->getCommitCount())))
->setHref($r->getURI());
}
if(!$compact) {
$item->setImageURI($r->getProfileImageURI());
$desc = id(new PhutilUTF8StringTruncator())
->setMaximumGlyphs(120)
->truncateString($r->getDetail('description'));
$desc = new PHUIRemarkupView($viewer, $desc);
$item->setSubHead($desc);
if($r->getMostRecentCommit()) {
$item->addIcon('',
phabricator_date(
$r->getMostRecentCommit()->getDateCreated(),
$viewer));
}
if($r->getProjectPHIDs()) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->witHPHIDs($r->getProjectPHIDs())
->execute();
$project_handles = array_select_keys(
$handles,
$r->getProjectPHIDs());
if ($project_handles) {
$item->addAttribute(
id(new PHUIHandleTagListView())
->setSlim(true)
->setHandles($project_handles));
}
}
}
$list->addItem($item);
}
if($pager->willShowPagingControls()) {
$pager_item = id(new PHUIObjectItemView())
->appendChild($pager);
$list->addItem($pager_item);
}
$box = id(new PHUIObjectBoxView())
->setObjectList($list);
if($title) {
$header = id(new PHUIHeaderView())
->setHeader($title);
$box->setHeader($header);
}
if($order == 'users') {
$repo_phids = ipull($repo, 'phid');
} else {
$repo_phids = mpull($repo, 'getPHID');
}
return $box;
}
private function buildPresentationPanel() {
$viewer = $this->getViewer();
$content = pht(<<<EOF
## c4science.ch
Infrastructure for scientific code co-creation, curation, sharing and testing. Available to the entire Swiss universities community and accessible to external collaborators.
Hosted on [[https://www.switch.ch/engines/ | SWITCHengines]], managed by [[http://scitas.epfl.ch/ | EPFL-SCITAS]], created via [[https://www.enhancer.ch/ | EnhanceR]], a [[https://www.swissuniversities.ch/ | Swissuniversities]] funded project.
## {icon sign-in} Login
[[ /auth/start/ | Login ]] with SwitchAAI (for Swiss universities), Google, Github or local account.
EOF
);
$remarkup = new PHUIRemarkupView($viewer, $content);
$box = id(new PHUIObjectBoxView())
->appendChild($remarkup);
return $box;
}
}

Event Timeline