Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/auth/application/PhabricatorApplicationAuth.php b/src/applications/auth/application/PhabricatorApplicationAuth.php
index 76c95323fd..9781347f78 100644
--- a/src/applications/auth/application/PhabricatorApplicationAuth.php
+++ b/src/applications/auth/application/PhabricatorApplicationAuth.php
@@ -1,93 +1,107 @@
<?php
final class PhabricatorApplicationAuth extends PhabricatorApplication {
public function canUninstall() {
return false;
}
public function getBaseURI() {
return '/auth/';
}
public function getIconName() {
return 'authentication';
}
public function getHelpURI() {
// NOTE: Although reasonable help exists for this in "Configuring Accounts
// and Registration", specifying a help URI here means we get the menu
// item in all the login/link interfaces, which is confusing and not
// helpful.
// TODO: Special case this, or split the auth and auth administration
// applications?
return null;
}
public function buildMainMenuItems(
PhabricatorUser $user,
PhabricatorController $controller = null) {
$items = array();
if ($user->isLoggedIn()) {
$item = id(new PHUIListItemView())
->addClass('core-menu-item')
->setName(pht('Log Out'))
->setIcon('power')
->setWorkflow(true)
->setHref('/logout/')
->setSelected(($controller instanceof PhabricatorLogoutController));
$items[] = $item;
+ } else {
+ if ($controller instanceof PhabricatorAuthController) {
+ // Don't show the "Login" item on auth controllers, since they're
+ // generally all related to logging in anyway.
+ } else {
+ $item = id(new PHUIListItemView())
+ ->addClass('core-menu-item')
+ ->setName(pht('Log In'))
+ // TODO: Login icon?
+ ->setIcon('power')
+ ->setWorkflow(true)
+ ->setHref('/auth/login/');
+ $items[] = $item;
+ }
}
return $items;
}
public function getApplicationGroup() {
return self::GROUP_ADMIN;
}
public function getRoutes() {
return array(
'/auth/' => array(
'' => 'PhabricatorAuthListController',
'config/' => array(
'new/' => 'PhabricatorAuthNewController',
'new/(?P<className>[^/]+)/' => 'PhabricatorAuthEditController',
'edit/(?P<id>\d+)/' => 'PhabricatorAuthEditController',
'(?P<action>enable|disable)/(?P<id>\d+)/' =>
'PhabricatorAuthDisableController',
),
'login/(?P<pkey>[^/]+)/' => 'PhabricatorAuthLoginController',
'register/(?:(?P<akey>[^/]+)/)?' => 'PhabricatorAuthRegisterController',
'start/' => 'PhabricatorAuthStartController',
'validate/' => 'PhabricatorAuthValidateController',
'unlink/(?P<pkey>[^/]+)/' => 'PhabricatorAuthUnlinkController',
'(?P<action>link|refresh)/(?P<pkey>[^/]+)/'
=> 'PhabricatorAuthLinkController',
'confirmlink/(?P<akey>[^/]+)/'
=> 'PhabricatorAuthConfirmLinkController',
),
'/oauth/(?P<provider>\w+)/login/'
=> 'PhabricatorAuthOldOAuthRedirectController',
'/login/' => array(
'' => 'PhabricatorAuthStartController',
'email/' => 'PhabricatorEmailLoginController',
'etoken/(?P<token>\w+)/' => 'PhabricatorEmailTokenController',
'refresh/' => 'PhabricatorRefreshCSRFController',
'mustverify/' => 'PhabricatorMustVerifyEmailController',
),
'/emailverify/(?P<code>[^/]+)/' =>
'PhabricatorEmailVerificationController',
'/logout/' => 'PhabricatorLogoutController',
);
}
}
diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php
index c807ac7ddf..86009fd9fc 100644
--- a/src/applications/base/controller/PhabricatorController.php
+++ b/src/applications/base/controller/PhabricatorController.php
@@ -1,411 +1,411 @@
<?php
abstract class PhabricatorController extends AphrontController {
private $handles;
public function shouldRequireLogin() {
return true;
}
public function shouldRequireAdmin() {
return false;
}
public function shouldRequireEnabledUser() {
return true;
}
public function shouldAllowPublic() {
return false;
}
public function shouldRequireEmailVerification() {
return PhabricatorUserEmail::isEmailVerificationRequired();
}
public function willBeginExecution() {
$request = $this->getRequest();
if ($request->getUser()) {
// NOTE: Unit tests can set a user explicitly. Normal requests are not
// permitted to do this.
PhabricatorTestCase::assertExecutingUnitTests();
$user = $request->getUser();
} else {
$user = new PhabricatorUser();
$phusr = $request->getCookie('phusr');
$phsid = $request->getCookie('phsid');
if (strlen($phusr) && $phsid) {
$info = queryfx_one(
$user->establishConnection('r'),
'SELECT u.* FROM %T u JOIN %T s ON u.phid = s.userPHID
AND s.type LIKE %> AND s.sessionKey = %s',
$user->getTableName(),
'phabricator_session',
'web-',
PhabricatorHash::digest($phsid));
if ($info) {
$user->loadFromArray($info);
}
}
$request->setUser($user);
}
$translation = $user->getTranslation();
if ($translation &&
$translation != PhabricatorEnv::getEnvConfig('translation.provider')) {
$translation = newv($translation, array());
PhutilTranslator::getInstance()
->setLanguage($translation->getLanguage())
->addTranslations($translation->getTranslations());
}
$preferences = $user->loadPreferences();
if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) {
$dark_console = PhabricatorUserPreferences::PREFERENCE_DARK_CONSOLE;
if ($preferences->getPreference($dark_console) ||
PhabricatorEnv::getEnvConfig('darkconsole.always-on')) {
$console = new DarkConsoleCore();
$request->getApplicationConfiguration()->setConsole($console);
}
}
- if ($user->getIsDisabled() && $this->shouldRequireEnabledUser()) {
- $disabled_user_controller = new PhabricatorDisabledUserController(
- $request);
- return $this->delegateToController($disabled_user_controller);
+ if ($this->shouldRequireEnabledUser()) {
+ if ($user->isLoggedIn() && !$user->getIsApproved()) {
+ $controller = new PhabricatorAuthNeedsApprovalController($request);
+ return $this->delegateToController($controller);
+ }
+ if ($user->getIsDisabled()) {
+ $controller = new PhabricatorDisabledUserController($request);
+ return $this->delegateToController($controller);
+ }
}
$event = new PhabricatorEvent(
PhabricatorEventType::TYPE_CONTROLLER_CHECKREQUEST,
array(
'request' => $request,
'controller' => $this,
));
$event->setUser($user);
PhutilEventEngine::dispatchEvent($event);
$checker_controller = $event->getValue('controller');
if ($checker_controller != $this) {
return $this->delegateToController($checker_controller);
}
if ($this->shouldRequireLogin()) {
// This actually means we need either:
// - a valid user, or a public controller; and
// - permission to see the application.
$auth_class = 'PhabricatorApplicationAuth';
$auth_application = PhabricatorApplication::getByClass($auth_class);
$allow_public = $this->shouldAllowPublic() &&
PhabricatorEnv::getEnvConfig('policy.allow-public');
// If this controller isn't public, and the user isn't logged in, require
// login.
if (!$allow_public && !$user->isLoggedIn()) {
$login_controller = new PhabricatorAuthStartController($request);
$this->setCurrentApplication($auth_application);
return $this->delegateToController($login_controller);
}
if ($user->isLoggedIn()) {
if ($this->shouldRequireEmailVerification()) {
if (!$user->getIsEmailVerified()) {
$controller = new PhabricatorMustVerifyEmailController($request);
$this->setCurrentApplication($auth_application);
return $this->delegateToController($controller);
}
}
- if (!$user->getIsApproved()) {
- $controller = new PhabricatorAuthNeedsApprovalController($request);
- $this->setCurrentApplication($auth_application);
- return $this->delegateToController($controller);
- }
}
// If the user doesn't have access to the application, don't let them use
// any of its controllers. We query the application in order to generate
// a policy exception if the viewer doesn't have permission.
$application = $this->getCurrentApplication();
if ($application) {
id(new PhabricatorApplicationQuery())
->setViewer($user)
->withPHIDs(array($application->getPHID()))
->executeOne();
}
}
// NOTE: We do this last so that users get a login page instead of a 403
// if they need to login.
if ($this->shouldRequireAdmin() && !$user->getIsAdmin()) {
return new Aphront403Response();
}
}
public function buildStandardPageView() {
$view = new PhabricatorStandardPageView();
$view->setRequest($this->getRequest());
$view->setController($this);
return $view;
}
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->appendChild($view);
$response = new AphrontWebpageResponse();
$response->setContent($page->render());
return $response;
}
public function getApplicationURI($path = '') {
if (!$this->getCurrentApplication()) {
throw new Exception("No application!");
}
return $this->getCurrentApplication()->getApplicationURI($path);
}
public function buildApplicationPage($view, array $options) {
$page = $this->buildStandardPageView();
$title = PhabricatorEnv::getEnvConfig('phabricator.serious-business') ?
'Phabricator' :
pht('Bacon Ice Cream for Breakfast');
$application = $this->getCurrentApplication();
$page->setTitle(idx($options, 'title', $title));
if ($application) {
$page->setApplicationName($application->getName());
if ($application->getTitleGlyph()) {
$page->setGlyph($application->getTitleGlyph());
}
}
if (!($view instanceof AphrontSideNavFilterView)) {
$nav = new AphrontSideNavFilterView();
$nav->appendChild($view);
$view = $nav;
}
$user = $this->getRequest()->getUser();
$view->setUser($user);
$page->appendChild($view);
$object_phids = idx($options, 'pageObjects', array());
if ($object_phids) {
$page->appendPageObjects($object_phids);
foreach ($object_phids as $object_phid) {
PhabricatorFeedStoryNotification::updateObjectNotificationViews(
$user,
$object_phid);
}
}
if (idx($options, 'device')) {
$page->setDeviceReady(true);
}
$page->setShowChrome(idx($options, 'chrome', true));
$application_menu = $this->buildApplicationMenu();
if ($application_menu) {
$page->setApplicationMenu($application_menu);
}
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
public function didProcessRequest($response) {
$request = $this->getRequest();
$response->setRequest($request);
$seen = array();
while ($response instanceof AphrontProxyResponse) {
$hash = spl_object_hash($response);
if (isset($seen[$hash])) {
$seen[] = get_class($response);
throw new Exception(
"Cycle while reducing proxy responses: ".
implode(' -> ', $seen));
}
$seen[$hash] = get_class($response);
$response = $response->reduceProxyResponse();
}
if ($response instanceof AphrontDialogResponse) {
if (!$request->isAjax()) {
$view = new PhabricatorStandardPageView();
$view->setRequest($request);
$view->setController($this);
$view->appendChild(phutil_tag(
'div',
array('style' => 'padding: 2em 0;'),
$response->buildResponseString()));
$page_response = new AphrontWebpageResponse();
$page_response->setContent($view->render());
$page_response->setHTTPResponseCode($response->getHTTPResponseCode());
return $page_response;
} else {
$response->getDialog()->setIsStandalone(true);
return id(new AphrontAjaxResponse())
->setContent(array(
'dialog' => $response->buildResponseString(),
));
}
} else if ($response instanceof AphrontRedirectResponse) {
if ($request->isAjax()) {
return id(new AphrontAjaxResponse())
->setContent(
array(
'redirect' => $response->getURI(),
));
}
}
return $response;
}
protected function getHandle($phid) {
if (empty($this->handles[$phid])) {
throw new Exception(
"Attempting to access handle which wasn't loaded: {$phid}");
}
return $this->handles[$phid];
}
protected function loadHandles(array $phids) {
$phids = array_filter($phids);
$this->handles = $this->loadViewerHandles($phids);
return $this;
}
protected function getLoadedHandles() {
return $this->handles;
}
protected function loadViewerHandles(array $phids) {
return id(new PhabricatorHandleQuery())
->setViewer($this->getRequest()->getUser())
->withPHIDs($phids)
->execute();
}
/**
* Render a list of links to handles, identified by PHIDs. The handles must
* already be loaded.
*
* @param list<phid> List of PHIDs to render links to.
* @param string Style, one of "\n" (to put each item on its own line)
* or "," (to list items inline, separated by commas).
* @return string Rendered list of handle links.
*/
protected function renderHandlesForPHIDs(array $phids, $style = "\n") {
$style_map = array(
"\n" => phutil_tag('br'),
',' => ', ',
);
if (empty($style_map[$style])) {
throw new Exception("Unknown handle list style '{$style}'!");
}
return implode_selected_handle_links($style_map[$style],
$this->getLoadedHandles(),
array_filter($phids));
}
protected function buildApplicationMenu() {
return null;
}
protected function buildApplicationCrumbs() {
$crumbs = array();
$application = $this->getCurrentApplication();
if ($application) {
$sprite = $application->getIconName();
if (!$sprite) {
$sprite = 'application';
}
$crumbs[] = id(new PhabricatorCrumbView())
->setHref($this->getApplicationURI())
->setIcon($sprite);
}
$view = new PhabricatorCrumbsView();
foreach ($crumbs as $crumb) {
$view->addCrumb($crumb);
}
return $view;
}
protected function hasApplicationCapability($capability) {
return PhabricatorPolicyFilter::hasCapability(
$this->getRequest()->getUser(),
$this->getCurrentApplication(),
$capability);
}
protected function requireApplicationCapability($capability) {
PhabricatorPolicyFilter::requireCapability(
$this->getRequest()->getUser(),
$this->getCurrentApplication(),
$capability);
}
protected function explainApplicationCapability(
$capability,
$positive_message,
$negative_message) {
$can_act = $this->hasApplicationCapability($capability);
if ($can_act) {
$message = $positive_message;
$icon_name = 'enable-grey';
} else {
$message = $negative_message;
$icon_name = 'lock';
}
$icon = id(new PHUIIconView())
->setSpriteSheet(PHUIIconView::SPRITE_ICONS)
->setSpriteIcon($icon_name);
require_celerity_resource('policy-css');
$phid = $this->getCurrentApplication()->getPHID();
$explain_uri = "/policy/explain/{$phid}/{$capability}/";
$message = phutil_tag(
'div',
array(
'class' => 'policy-capability-explanation',
),
array(
$icon,
javelin_tag(
'a',
array(
'href' => $explain_uri,
'sigil' => 'workflow',
),
$message),
));
return array($can_act, $message);
}
}
diff --git a/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php b/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php
index 28e7ca618e..1f5c94a498 100644
--- a/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php
+++ b/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php
@@ -1,268 +1,282 @@
<?php
final class PhabricatorAccessControlTestCase
extends PhabricatorTestCase {
protected function getPhabricatorTestCaseConfiguration() {
return array(
self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => true,
);
}
public function testControllerAccessControls() {
$root = dirname(phutil_get_library_root('phabricator'));
require_once $root.'/support/PhabricatorStartup.php';
$application_configuration = new AphrontDefaultApplicationConfiguration();
$host = 'meow.example.com';
$_SERVER['REQUEST_METHOD'] = 'GET';
$request = id(new AphrontRequest($host, '/'))
->setApplicationConfiguration($application_configuration)
->setRequestData(array());
$controller = new PhabricatorTestController($request);
$u_public = id(new PhabricatorUser())
->setUsername('public');
$u_unverified = $this->generateNewTestUser()
->setUsername('unverified')
->save();
$u_unverified->setIsEmailVerified(0)->save();
$u_normal = $this->generateNewTestUser()
->setUsername('normal')
->save();
$u_disabled = $this->generateNewTestUser()
->setIsDisabled(true)
->setUsername('disabled')
->save();
$u_admin = $this->generateNewTestUser()
->setIsAdmin(true)
->setUsername('admin')
->save();
+ $u_notapproved = $this->generateNewTestUser()
+ ->setIsApproved(0)
+ ->setUsername('notapproved')
+ ->save();
+
$env = PhabricatorEnv::beginScopedEnv();
$env->overrideEnvConfig('phabricator.base-uri', 'http://'.$host);
$env->overrideEnvConfig('policy.allow-public', false);
$env->overrideEnvConfig('auth.require-email-verification', false);
$env->overrideEnvConfig('auth.email-domains', array());
// Test standard defaults.
$this->checkAccess(
"Default",
id(clone $controller),
$request,
array(
$u_normal,
$u_admin,
$u_unverified,
),
array(
$u_public,
$u_disabled,
+ $u_notapproved,
));
// Test email verification.
$env->overrideEnvConfig('auth.require-email-verification', true);
$this->checkAccess(
"Email Verification Required",
id(clone $controller),
$request,
array(
$u_normal,
$u_admin,
),
array(
$u_unverified,
$u_public,
$u_disabled,
+ $u_notapproved,
));
$this->checkAccess(
"Email Verification Required, With Exception",
id(clone $controller)->setConfig('email', false),
$request,
array(
$u_normal,
$u_admin,
$u_unverified,
),
array(
$u_public,
$u_disabled,
+ $u_notapproved,
));
$env->overrideEnvConfig('auth.require-email-verification', false);
// Test admin access.
$this->checkAccess(
"Admin Required",
id(clone $controller)->setConfig('admin', true),
$request,
array(
$u_admin,
),
array(
$u_normal,
$u_unverified,
$u_public,
$u_disabled,
+ $u_notapproved,
));
// Test disabled access.
$this->checkAccess(
"Allow Disabled",
id(clone $controller)->setConfig('enabled', false),
$request,
array(
$u_normal,
$u_unverified,
$u_admin,
$u_disabled,
+ $u_notapproved,
),
array(
$u_public,
));
// Test no login required.
$this->checkAccess(
"No Login Required",
id(clone $controller)->setConfig('login', false),
$request,
array(
$u_normal,
$u_unverified,
$u_admin,
$u_public,
),
array(
$u_disabled,
+ $u_notapproved,
));
// Test public access.
$this->checkAccess(
"No Login Required",
id(clone $controller)->setConfig('public', true),
$request,
array(
$u_normal,
$u_unverified,
$u_admin,
),
array(
$u_disabled,
$u_public,
));
$env->overrideEnvConfig('policy.allow-public', true);
$this->checkAccess(
"Public + configured",
id(clone $controller)->setConfig('public', true),
$request,
array(
$u_normal,
$u_unverified,
$u_admin,
$u_public,
),
array(
$u_disabled,
+ $u_notapproved,
));
$env->overrideEnvConfig('policy.allow-public', false);
$app = PhabricatorApplication::getByClass('PhabricatorApplicationTest');
$app->reset();
$app->setPolicy(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicies::POLICY_NOONE);
$app_controller = id(clone $controller)->setCurrentApplication($app);
$this->checkAccess(
"Application Controller",
$app_controller,
$request,
array(
),
array(
$u_normal,
$u_unverified,
$u_admin,
$u_public,
$u_disabled,
+ $u_notapproved,
));
$this->checkAccess(
"Application Controller",
id(clone $app_controller)->setConfig('login', false),
$request,
array(
$u_normal,
$u_unverified,
$u_admin,
$u_public,
),
array(
$u_disabled,
+ $u_notapproved,
));
}
private function checkAccess(
$label,
$controller,
$request,
array $yes,
array $no) {
foreach ($yes as $user) {
$request->setUser($user);
$uname = $user->getUsername();
try {
$result = id(clone $controller)->willBeginExecution();
} catch (Exception $ex) {
$result = $ex;
}
$this->assertEqual(
true,
($result === null),
"Expect user '{$uname}' to be allowed access to '{$label}'.");
}
foreach ($no as $user) {
$request->setUser($user);
$uname = $user->getUsername();
try {
$result = id(clone $controller)->willBeginExecution();
} catch (Exception $ex) {
$result = $ex;
}
$this->assertEqual(
false,
($result === null),
"Expect user '{$uname}' to be denied access to '{$label}'.");
}
}
}
diff --git a/src/applications/people/application/PhabricatorApplicationPeople.php b/src/applications/people/application/PhabricatorApplicationPeople.php
index e8bbabc51e..c1485b95fa 100644
--- a/src/applications/people/application/PhabricatorApplicationPeople.php
+++ b/src/applications/people/application/PhabricatorApplicationPeople.php
@@ -1,99 +1,125 @@
<?php
final class PhabricatorApplicationPeople extends PhabricatorApplication {
public function getShortDescription() {
return 'User Accounts';
}
public function getBaseURI() {
return '/people/';
}
public function getTitleGlyph() {
return "\xE2\x99\x9F";
}
public function getIconName() {
return 'people';
}
public function getFlavorText() {
return pht('Sort of a social utility.');
}
public function getApplicationGroup() {
return self::GROUP_ORGANIZATION;
}
public function canUninstall() {
return false;
}
public function getEventListeners() {
return array(
new PhabricatorPeopleHovercardEventListener(),
);
}
public function getRoutes() {
return array(
'/people/' => array(
'(query/(?P<key>[^/]+)/)?' => 'PhabricatorPeopleListController',
'logs/' => 'PhabricatorPeopleLogsController',
'approve/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleApproveController',
'disable/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleDisableController',
'edit/(?:(?P<id>[1-9]\d*)/(?:(?P<view>\w+)/)?)?'
=> 'PhabricatorPeopleEditController',
'ldap/' => 'PhabricatorPeopleLdapController',
'editprofile/(?P<id>[1-9]\d*)/' =>
'PhabricatorPeopleProfileEditController',
'picture/(?P<id>[1-9]\d*)/' =>
'PhabricatorPeopleProfilePictureController',
),
'/p/(?P<username>[\w._-]+)/'
=> 'PhabricatorPeopleProfileController',
);
}
public function getRemarkupRules() {
return array(
new PhabricatorRemarkupRuleMention(),
);
}
+ public function loadStatus(PhabricatorUser $user) {
+ if (!$user->getIsAdmin()) {
+ return array();
+ }
+
+ $need_approval = id(new PhabricatorPeopleQuery())
+ ->setViewer($user)
+ ->withIsApproved(false)
+ ->execute();
+
+ if (!$need_approval) {
+ return array();
+ }
+
+ $status = array();
+
+ $count = count($need_approval);
+ $type = PhabricatorApplicationStatusView::TYPE_NEEDS_ATTENTION;
+ $status[] = id(new PhabricatorApplicationStatusView())
+ ->setType($type)
+ ->setText(pht('%d User(s) Need Approval', $count))
+ ->setCount($count);
+
+ return $status;
+ }
+
public function buildMainMenuItems(
PhabricatorUser $user,
PhabricatorController $controller = null) {
$items = array();
- if ($user->isLoggedIn()) {
+ if ($user->isLoggedIn() && $user->isUserActivated()) {
$image = $user->loadProfileImageURI();
$item = new PHUIListItemView();
$item->setName($user->getUsername());
$item->setHref('/p/'.$user->getUsername().'/');
$item->addClass('core-menu-item');
$classes = array(
'phabricator-core-menu-icon',
'phabricator-core-menu-profile-image',
);
$item->appendChild(
phutil_tag(
'span',
array(
'class' => implode(' ', $classes),
'style' => 'background-image: url('.$image.')',
),
''));
$items[] = $item;
}
return $items;
}
}
diff --git a/src/applications/settings/application/PhabricatorApplicationSettings.php b/src/applications/settings/application/PhabricatorApplicationSettings.php
index 6a7d6096ff..e42ba50229 100644
--- a/src/applications/settings/application/PhabricatorApplicationSettings.php
+++ b/src/applications/settings/application/PhabricatorApplicationSettings.php
@@ -1,54 +1,54 @@
<?php
final class PhabricatorApplicationSettings extends PhabricatorApplication {
public function getBaseURI() {
return '/settings/';
}
public function getShortDescription() {
return 'User Preferences';
}
public function getIconName() {
return 'settings';
}
public function canUninstall() {
return false;
}
public function getRoutes() {
return array(
'/settings/' => array(
'(?:panel/(?P<key>[^/]+)/)?' => 'PhabricatorSettingsMainController',
'adjust/' => 'PhabricatorSettingsAdjustController',
),
);
}
public function getApplicationGroup() {
return self::GROUP_UTILITIES;
}
public function buildMainMenuItems(
PhabricatorUser $user,
PhabricatorController $controller = null) {
$items = array();
- if ($user->isLoggedIn()) {
+ if ($user->isLoggedIn() && $user->isUserActivated()) {
$selected = ($controller instanceof PhabricatorSettingsMainController);
$item = new PHUIListItemView();
$item->setName(pht('Settings'));
$item->setIcon('settings');
$item->addClass('core-menu-item');
$item->setSelected($selected);
$item->setHref('/settings/');
$items[] = $item;
}
return $items;
}
}
diff --git a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
index f49c69ecaf..7a36a54f41 100644
--- a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
+++ b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
@@ -1,816 +1,821 @@
<?php
abstract class PhabricatorBaseEnglishTranslation
extends PhabricatorTranslation {
final public function getLanguage() {
return 'en';
}
public function getTranslations() {
return array(
'These %d configuration value(s) are related:' => array(
'This configuration value is related:',
'These configuration values are related:',
),
'Differential Revision(s)' => array(
'Differential Revision',
'Differential Revisions',
),
'file(s)' => array('file', 'files'),
'Maniphest Task(s)' => array('Maniphest Task', 'Maniphest Tasks'),
'Task(s)' => array('Task', 'Tasks'),
'Please fix these errors and try again.' => array(
'Please fix this error and try again.',
'Please fix these errors and try again.',
),
'%d Error(s)' => array('%d Error', '%d Errors'),
'%d Warning(s)' => array('%d Warning', '%d Warnings'),
'%d Auto-Fix(es)' => array('%d Auto-Fix', '%d Auto-Fixes'),
'%d Advice(s)' => array('%d Advice', '%d Pieces of Advice'),
'%d Detail(s)' => array('%d Detail', '%d Details'),
'(%d line(s))' => array('(%d line)', '(%d lines)'),
'COMMIT(S)' => array('COMMIT', 'COMMITS'),
'%d line(s)' => array('%d line', '%d lines'),
'%d path(s)' => array('%d path', '%d paths'),
'%d diff(s)' => array('%d diff', '%d diffs'),
'added %d commit(s): %s' => array(
'added commit: %2$s',
'added commits: %2$s',
),
'removed %d commit(s): %s' => array(
'removed commit: %2$s',
'removed commits: %2$s',
),
'changed %d commit(s), added %d: %s; removed %d: %s' =>
'changed commits, added: %3$s; removed: %5$s',
'ATTACHED %d COMMIT(S)' => array(
'ATTACHED COMMIT',
'ATTACHED COMMITS',
),
'added %d mock(s): %s' => array(
'added a mock: %2$s',
'added mocks: %2$s',
),
'removed %d mock(s): %s' => array(
'removed a mock: %2$s',
'removed mocks: %2$s',
),
'changed %d mock(s), added %d: %s; removed %d: %s' =>
'changed mocks, added: %3$s; removed: %5$s',
'ATTACHED %d MOCK(S)' => array(
'ATTACHED MOCK',
'ATTACHED MOCKS',
),
'added %d dependencie(s): %s' => array(
'added dependency: %2$s',
'added dependencies: %2$s',
),
'added %d dependent task(s): %s' => array(
'added dependent task: %2$s',
'added dependent tasks: %2$s',
),
'removed %d dependencie(s): %s' => array(
'removed dependency: %2$s',
'removed dependencies: %2$s',
),
'removed %d dependent task(s): %s' => array(
'removed dependent task: %2$s',
'removed dependent tasks: %2$s',
),
'changed %d dependencie(s), added %d: %s; removed %d: %s' =>
'changed dependencies, added: %3$s; removed: %5$s',
'changed %d dependent task(s), added %d: %s; removed %d: %s',
'changed dependent tasks, added: %3$s; removed: %5$s',
'DEPENDENT %d TASK(s)' => array(
'DEPENDENT TASK',
'DEPENDENT TASKS',
),
'DEPENDS ON %d TASK(S)' => array(
'DEPENDS ON TASK',
'DEPENDS ON TASKS',
),
'DIFFERENTIAL %d REVISION(S)' => array(
'DIFFERENTIAL REVISION',
'DIFFERENTIAL REVISIONS',
),
'added %d revision(s): %s' => array(
'added revision: %2$s',
'added revisions: %2$s',
),
'removed %d revision(s): %s' => array(
'removed revision: %2$s',
'removed revisions: %2$s',
),
'changed %d revision(s), added %d: %s; removed %d: %s' =>
'changed revisions, added %3$s; removed %5$s',
'%s edited revision(s), added %d: %s; removed %d: %s.' =>
'%s edited revisions, added: %3$s; removed: %5$s',
'There are %d raw fact(s) in storage.' => array(
'There is %d raw fact in storage.',
'There are %d raw facts in storage.',
),
'There are %d aggregate fact(s) in storage.' => array(
'There is %d aggregate fact in storage.',
'There are %d aggregate facts in storage.',
),
'%d Commit(s) Awaiting Audit' => array(
'%d Commit Awaiting Audit',
'%d Commits Awaiting Audit',
),
'%d Problem Commit(s)' => array(
'%d Problem Commit',
'%d Problem Commits',
),
'%d Review(s) Blocking Others' => array(
'%d Review Blocking Others',
'%d Reviews Blocking Others',
),
'%d Review(s) Need Attention' => array(
'%d Review Needs Attention',
'%d Reviews Need Attention',
),
'%d Review(s) Waiting on Others' => array(
'%d Review Waiting on Others',
'%d Reviews Waiting on Others',
),
'%d Flagged Object(s)' => array(
'%d Flagged Object',
'%d Flagged Objects',
),
'%d Unbreak Now Task(s)!' => array(
'%d Unbreak Now Task!',
'%d Unbreak Now Tasks!',
),
'%d Assigned Task(s)' => array(
'%d Assigned Task',
'%d Assigned Tasks',
),
'Show %d Lint Message(s)' => array(
'Show %d Lint Message',
'Show %d Lint Messages',
),
'Hide %d Lint Message(s)' => array(
'Hide %d Lint Message',
'Hide %d Lint Messages',
),
'Switch for %d Lint Message(s)' => array(
'Switch for %d Lint Message',
'Switch for %d Lint Messages',
),
'%d Lint Message(s)' => array(
'%d Lint Message',
'%d Lint Messages',
),
'This is a binary file. It is %s byte(s) in length.' => array(
'This is a binary file. It is %s byte in length.',
'This is a binary file. It is %s bytes in length.',
),
'%d Action(s) Have No Effect' => array(
'Action Has No Effect',
'Actions Have No Effect',
),
'%d Action(s) With No Effect' => array(
'Action With No Effect',
'Actions With No Effect',
),
'%s edited post(s), added %d: %s; removed %d: %s.' =>
'%s edited posts, added: %3$s; removed: %5$s',
'%s added %d post(s): %s.' => array(
array(
'%s added a post: %3$s.',
'%s added posts: %3$s.',
),
),
'%s removed %d post(s): %s.' => array(
array(
'%s removed a post: %3$s.',
'%s removed posts: %3$s.',
),
),
'%s edited blog(s), added %d: %s; removed %d: %s.' =>
'%s edited blogs, added: %3$s; removed: %5$s',
'%s added %d blog(s): %s.' => array(
array(
'%s added a blog: %3$s.',
'%s added blogs: %3$s.',
),
),
'%s removed %d blog(s): %s.' => array(
array(
'%s removed a blog: %3$s.',
'%s removed blogs: %3$s.',
),
),
'%s edited blogger(s), added %d: %s; removed %d: %s.' =>
'%s edited bloggers, added: %3$s; removed: %5$s',
'%s added %d blogger(s): %s.' => array(
array(
'%s added a blogger: %3$s.',
'%s added bloggers: %3$s.',
),
),
'%s removed %d blogger(s): %s.' => array(
array(
'%s removed a blogger: %3$s.',
'%s removed bloggers: %3$s.',
),
),
'%s edited member(s), added %d: %s; removed %d: %s.' =>
'%s edited members, added: %3$s; removed: %5$s',
'%s added %d member(s): %s.' => array(
array(
'%s added a member: %3$s.',
'%s added members: %3$s.',
),
),
'%s removed %d member(s): %s.' => array(
array(
'%s removed a member: %3$s.',
'%s removed members: %3$s.',
),
),
'%s edited project(s), added %d: %s; removed %d: %s.' =>
'%s edited projects, added: %3$s; removed: %5$s',
'%s added %d project(s): %s.' => array(
array(
'%s added a project: %3$s.',
'%s added projects: %3$s.',
),
),
'%s removed %d project(s): %s.' => array(
array(
'%s removed a project: %3$s.',
'%s removed projects: %3$s.',
),
),
'%s changed project(s) of %s, added %d: %s; removed %d: %s' =>
'%s changed projects of %s, added: %4$s; removed: %6$s',
'%s added %d project(s) to %s: %s' => array(
array(
'%s added a project to %3$s: %4$s',
'%s added projects to %3$s: %4$s',
),
),
'%s removed %d project(s) from %s: %s' => array(
array(
'%s removed a project from %3$s: %4$s',
'%s removed projects from %3$s: %4$s',
),
),
'%s edited voting user(s), added %d: %s; removed %d: %s.' =>
'%s edited voting users, added: %3$s; removed: %5$s',
'%s added %d voting user(s): %s.' => array(
array(
'%s added a voting user: %3$s.',
'%s added voting users: %3$s.',
),
),
'%s removed %d voting user(s): %s.' => array(
array(
'%s removed a voting user: %3$s.',
'%s removed voting users: %3$s.',
),
),
'%s edited answer(s), added %d: %s; removed %d: %s.' =>
'%s edited answers, added: %3$s; removed: %5$s',
'%s added %d answer(s): %s.' => array(
array(
'%s added a answer: %3$s.',
'%s added answers: %3$s.',
),
),
'%s removed %d answer(s): %s.' => array(
array(
'%s removed a answer: %3$s.',
'%s removed answers: %3$s.',
),
),
'%s edited question(s), added %d: %s; removed %d: %s.' =>
'%s edited questions, added: %3$s; removed: %5$s',
'%s added %d question(s): %s.' => array(
array(
'%s added a question: %3$s.',
'%s added questions: %3$s.',
),
),
'%s removed %d question(s): %s.' => array(
array(
'%s removed a question: %3$s.',
'%s removed questions: %3$s.',
),
),
'%s edited mock(s), added %d: %s; removed %d: %s.' =>
'%s edited mocks, added: %3$s; removed: %5$s',
'%s added %d mock(s): %s.' => array(
array(
'%s added a mock: %3$s.',
'%s added mocks: %3$s.',
),
),
'%s removed %d mock(s): %s.' => array(
array(
'%s removed a mock: %3$s.',
'%s removed mocks: %3$s.',
),
),
'%s edited task(s), added %d: %s; removed %d: %s.' =>
'%s edited tasks, added: %3$s; removed: %5$s',
'%s added %d task(s): %s.' => array(
array(
'%s added a task: %3$s.',
'%s added tasks: %3$s.',
),
),
'%s removed %d task(s): %s.' => array(
array(
'%s removed a task: %3$s.',
'%s removed tasks: %3$s.',
),
),
'%s edited file(s), added %d: %s; removed %d: %s.' =>
'%s edited files, added: %3$s; removed: %5$s',
'%s added %d file(s): %s.' => array(
array(
'%s added a file: %3$s.',
'%s added files: %3$s.',
),
),
'%s removed %d file(s): %s.' => array(
array(
'%s removed a file: %3$s.',
'%s removed files: %3$s.',
),
),
'%s edited account(s), added %d: %s; removed %d: %s.' =>
'%s edited accounts, added: %3$s; removed: %5$s',
'%s added %d account(s): %s.' => array(
array(
'%s added a account: %3$s.',
'%s added accounts: %3$s.',
),
),
'%s removed %d account(s): %s.' => array(
array(
'%s removed a account: %3$s.',
'%s removed accounts: %3$s.',
),
),
'%s edited charge(s), added %d: %s; removed %d: %s.' =>
'%s edited charges, added: %3$s; removed: %5$s',
'%s added %d charge(s): %s.' => array(
array(
'%s added a charge: %3$s.',
'%s added charges: %3$s.',
),
),
'%s removed %d charge(s): %s.' => array(
array(
'%s removed a charge: %3$s.',
'%s removed charges: %3$s.',
),
),
'%s edited purchase(s), added %d: %s; removed %d: %s.' =>
'%s edited purchases, added: %3$s; removed: %5$s',
'%s added %d purchase(s): %s.' => array(
array(
'%s added a purchase: %3$s.',
'%s added purchases: %3$s.',
),
),
'%s removed %d purchase(s): %s.' => array(
array(
'%s removed a purchase: %3$s.',
'%s removed purchases: %3$s.',
),
),
'%s edited contributor(s), added %d: %s; removed %d: %s.' =>
'%s edited contributors, added: %3$s; removed: %5$s',
'%s added %d contributor(s): %s.' => array(
array(
'%s added a contributor: %3$s.',
'%s added contributors: %3$s.',
),
),
'%s removed %d contributor(s): %s.' => array(
array(
'%s removed a contributor: %3$s.',
'%s removed contributors: %3$s.',
),
),
'%s edited reviewer(s), added %d: %s; removed %d: %s.' =>
'%s edited reviewers, added: %3$s; removed: %5$s',
'%s added %d reviewer(s): %s.' => array(
array(
'%s added a reviewer: %3$s.',
'%s added reviewers: %3$s.',
),
),
'%s removed %d reviewer(s): %s.' => array(
array(
'%s removed a reviewer: %3$s.',
'%s removed reviewers: %3$s.',
),
),
'%s edited object(s), added %d: %s; removed %d: %s.' =>
'%s edited objects, added: %3$s; removed: %5$s',
'%s added %d object(s): %s.' => array(
array(
'%s added a object: %3$s.',
'%s added objects: %3$s.',
),
),
'%s removed %d object(s): %s.' => array(
array(
'%s removed a object: %3$s.',
'%s removed objects: %3$s.',
),
),
'%s edited subscriber(s), added %d: %s; removed %d: %s.' =>
'%s edited subscribers, added: %3$s; removed: %5$s',
'%s added %d subscriber(s): %s.' => array(
array(
'%s added a subscriber: %3$s.',
'%s added subscribers: %3$s.',
),
),
'%s removed %d subscriber(s): %s.' => array(
array(
'%s removed a subscriber: %3$s.',
'%s removed subscribers: %3$s.',
),
),
'%s edited unsubscriber(s), added %d: %s; removed %d: %s.' =>
'%s edited unsubscribers, added: %3$s; removed: %5$s',
'%s added %d unsubscriber(s): %s.' => array(
array(
'%s added a unsubscriber: %3$s.',
'%s added unsubscribers: %3$s.',
),
),
'%s removed %d unsubscriber(s): %s.' => array(
array(
'%s removed a unsubscriber: %3$s.',
'%s removed unsubscribers: %3$s.',
),
),
'%s edited participant(s), added %d: %s; removed %d: %s.' =>
'%s edited participants, added: %3$s; removed: %5$s',
'%s added %d participant(s): %s.' => array(
array(
'%s added a participant: %3$s.',
'%s added participants: %3$s.',
),
),
'%s removed %d participant(s): %s.' => array(
array(
'%s removed a participant: %3$s.',
'%s removed participants: %3$s.',
),
),
'%s edited image(s), added %d: %s; removed %d: %s.' =>
'%s edited images, added: %3$s; removed: %5$s',
'%s added %d image(s): %s.' => array(
array(
'%s added an image: %3$s.',
'%s added images: %3$s.',
),
),
'%s removed %d image(s): %s.' => array(
array(
'%s removed an image: %3$s.',
'%s removed images: %3$s.',
),
),
'%d people(s)' => array(
array(
'%d person',
'%d people',
),
),
'%s Line(s)' => array(
'%s Line',
'%s Lines',
),
"Indexing %d object(s) of type %s." => array(
"Indexing %d object of type %s.",
"Indexing %d object of type %s.",
),
'Run these %d command(s):' => array(
'Run this command:',
'Run these commands:',
),
'Install these %d PHP extension(s):' => array(
'Install this PHP extension:',
'Install these PHP extensions:',
),
'The current Phabricator configuration has these %d value(s):' => array(
'The current Phabricator configuration has this value:',
'The current Phabricator configuration has these values:',
),
'To update these %d value(s), run these command(s) from the command line:'
=> array(
'To update this value, run this command from the command line:',
'To update these values, run these commands from the command line:',
),
'You can update these %d value(s) here:' => array(
'You can update this value here:',
'You can update these values here:',
),
'The current PHP configuration has these %d value(s):' => array(
'The current PHP configuration has this value:',
'The current PHP configuration has these values:',
),
'To update these %d value(s), edit your PHP configuration file.' => array(
'To update this %d value, edit your PHP configuration file.',
'To update these %d values, edit your PHP configuration file.',
),
'To update these %d value(s), edit your PHP configuration file, located '.
'here:' => array(
'To update this value, edit your PHP configuration file, located '.
'here:',
'To update these values, edit your PHP configuration file, located '.
'here:',
),
'PHP also loaded these configuration file(s):' => array(
'PHP also loaded this configuration file:',
'PHP also loaded these configuration files:',
),
'You have %d unresolved setup issue(s)...' => array(
'You have an unresolved setup issue...',
'You have %d unresolved setup issues...',
),
'%s added %d inline comment(s).' => array(
array(
'%s added an inline comment.',
'%s added inline comments.',
),
),
'%d comment(s)' => array('%d comment', '%d comments'),
'%d rejection(s)' => array('%d rejection', '%d rejections'),
'%d update(s)' => array('%d update', '%d updates'),
'This configuration value is defined in these %d '.
'configuration source(s): %s.' => array(
'This configuration value is defined in this '.
'configuration source: %2$s.',
'This configuration value is defined in these %d '.
'configuration sources: %s.',
),
'%d Open Pull Request(s)' => array(
'%d Open Pull Request',
'%d Open Pull Requests',
),
'Stale (%s day(s))' => array(
'Stale (%s day)',
'Stale (%s days)',
),
'Old (%s day(s))' => array(
'Old (%s day)',
'Old (%s days)',
),
'%s Commit(s)' => array(
'%s Commit',
'%s Commits',
),
'%s added %d project(s): %s' => array(
array(
'%s added a project: %3$s',
'%s added projects: %3$s',
),
),
'%s removed %d project(s): %s' => array(
array(
'%s removed a project: %3$s',
'%s removed projects: %3$s',
),
),
'%s changed project(s), added %d: %s; removed %d: %s' =>
'%s changed projects, added: %3$s; removed: %5$s',
'%s attached %d file(s): %s' => array(
array(
'%s attached a file: %3$s',
'%s attached files: %3$s',
),
),
'%s detached %d file(s): %s' => array(
array(
'%s detached a file: %3$s',
'%s detached files: %3$s',
),
),
'%s changed file(s), attached %d: %s; detached %d: %s' =>
'%s changed files, attached: %3$s; detached: %5$s',
'%s added %d dependencie(s): %s.' => array(
array(
'%s added a dependency: %3$s',
'%s added a dependencies: %3$s',
),
),
'%s added %d dependent task(s): %s.' => array(
array(
'%s added a dependent task: %3$s',
'%s added dependent tasks: %3$s',
),
),
'%s removed %d dependencie(s): %s.' => array(
array(
'%s removed a dependency: %3$s.',
'%s removed dependencies: %3$s.',
),
),
'%s removed %d dependent task(s): %s.' => array(
array(
'%s removed a dependent task: %3$s.',
'%s removed dependent tasks: %3$s.',
),
),
'%s added %d revision(s): %s.' => array(
array(
'%s added a revision: %3$s.',
'%s added revisions: %3$s.',
),
),
'%s removed %d revision(s): %s.' => array(
array(
'%s removed a revision: %3$s.',
'%s removed revisions: %3$s.',
),
),
'%s added %d commit(s): %s.' => array(
array(
'%s added a commit: %3$s.',
'%s added commits: %3$s.',
),
),
'%s removed %d commit(s): %s.' => array(
array(
'%s removed a commit: %3$s.',
'%s removed commits: %3$s.',
),
),
'%s edited commit(s), added %d: %s; removed %d: %s.' =>
'%s edited commits, added %3$s; removed %5$s.',
'%s changed project member(s), added %d: %s; removed %d: %s' =>
'%s changed project members, added %3$s; removed %5$s',
'%s added %d project member(s): %s' => array(
array(
'%s added a member: %3$s',
'%s added members: %3$s',
),
),
'%s removed %d project member(s): %s' => array(
array(
'%s removed a member: %3$s',
'%s removed members: %3$s',
),
),
+ '%d User(s) Need Approval' => array(
+ '%d User Needs Approval',
+ '%d Users Need Approval',
+ ),
+
);
}
}
diff --git a/src/view/page/menu/PhabricatorMainMenuView.php b/src/view/page/menu/PhabricatorMainMenuView.php
index 9d8b25228d..179f93366a 100644
--- a/src/view/page/menu/PhabricatorMainMenuView.php
+++ b/src/view/page/menu/PhabricatorMainMenuView.php
@@ -1,402 +1,405 @@
<?php
final class PhabricatorMainMenuView extends AphrontView {
private $defaultSearchScope;
private $controller;
private $applicationMenu;
public function setApplicationMenu(PHUIListView $application_menu) {
$this->applicationMenu = $application_menu;
return $this;
}
public function getApplicationMenu() {
return $this->applicationMenu;
}
public function setController(PhabricatorController $controller) {
$this->controller = $controller;
return $this;
}
public function getController() {
return $this->controller;
}
public function setDefaultSearchScope($default_search_scope) {
$this->defaultSearchScope = $default_search_scope;
return $this;
}
public function getDefaultSearchScope() {
return $this->defaultSearchScope;
}
public function render() {
$user = $this->user;
require_celerity_resource('phabricator-main-menu-view');
$header_id = celerity_generate_unique_node_id();
$menus = array();
$alerts = array();
$search_button = '';
$app_button = '';
- if ($user->isLoggedIn()) {
+ if ($user->isLoggedIn() && $user->isUserActivated()) {
list($menu, $dropdowns) = $this->renderNotificationMenu();
$alerts[] = $menu;
$menus = array_merge($menus, $dropdowns);
$app_button = $this->renderApplicationMenuButton($header_id);
$search_button = $this->renderSearchMenuButton($header_id);
}
$search_menu = $this->renderPhabricatorSearchMenu();
if ($alerts) {
$alerts = phutil_tag(
'div',
array(
'class' => 'phabricator-main-menu-alerts',
),
$alerts);
}
$application_menu = $this->renderApplicationMenu();
return phutil_tag(
'div',
array(
'class' => 'phabricator-main-menu',
'id' => $header_id,
),
array(
$app_button,
$search_button,
$this->renderPhabricatorLogo(),
$alerts,
$application_menu,
$search_menu,
$menus,
));
}
private function renderSearch() {
$user = $this->user;
$result = null;
$keyboard_config = array(
'helpURI' => '/help/keyboardshortcut/',
);
- $show_search = ($user->isLoggedIn()) ||
- (PhabricatorEnv::getEnvConfig('policy.allow-public'));
+ if ($user->isLoggedIn()) {
+ $show_search = $user->isUserActivated();
+ } else {
+ $show_search = PhabricatorEnv::getEnvConfig('policy.allow-public');
+ }
if ($show_search) {
$search = new PhabricatorMainMenuSearchView();
$search->setUser($user);
$search->setScope($this->getDefaultSearchScope());
$result = $search;
$pref_shortcut = PhabricatorUserPreferences::PREFERENCE_SEARCH_SHORTCUT;
if ($user->loadPreferences()->getPreference($pref_shortcut, true)) {
$keyboard_config['searchID'] = $search->getID();
}
}
Javelin::initBehavior('phabricator-keyboard-shortcuts', $keyboard_config);
if ($result) {
$result = id(new PHUIListItemView())
->addClass('phabricator-main-menu-search')
->appendChild($result);
}
return $result;
}
public function renderApplicationMenuButton($header_id) {
$button_id = celerity_generate_unique_node_id();
return javelin_tag(
'a',
array(
'class' => 'phabricator-main-menu-expand-button '.
'phabricator-expand-search-menu',
'sigil' => 'jx-toggle-class',
'meta' => array(
'map' => array(
$header_id => 'phabricator-application-menu-expanded',
$button_id => 'menu-icon-app-blue',
),
),
),
phutil_tag(
'span',
array(
'class' => 'phabricator-menu-button-icon sprite-menu menu-icon-app',
'id' => $button_id,
),
''));
}
public function renderApplicationMenu() {
$user = $this->getUser();
$controller = $this->getController();
$applications = PhabricatorApplication::getAllInstalledApplications();
$actions = array();
foreach ($applications as $application) {
$app_actions = $application->buildMainMenuItems($user, $controller);
foreach ($app_actions as $action) {
$actions[] = $action;
}
}
$view = $this->getApplicationMenu();
if (!$view) {
$view = new PHUIListView();
}
$view->addClass('phabricator-dark-menu');
$view->addClass('phabricator-application-menu');
if ($actions) {
$view->addMenuItem(
id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_LABEL)
->setName(pht('Actions')));
foreach ($actions as $action) {
$icon = $action->getIcon();
if ($icon) {
if ($action->getSelected()) {
$action->appendChild($this->renderMenuIcon($icon.'-blue-large'));
} else {
$action->appendChild($this->renderMenuIcon($icon.'-light-large'));
}
}
$view->addMenuItem($action);
}
}
return $view;
}
public function renderSearchMenuButton($header_id) {
$button_id = celerity_generate_unique_node_id();
return javelin_tag(
'a',
array(
'class' => 'phabricator-main-menu-search-button '.
'phabricator-expand-application-menu',
'sigil' => 'jx-toggle-class',
'meta' => array(
'map' => array(
$header_id => 'phabricator-search-menu-expanded',
$button_id => 'menu-icon-search-blue',
),
),
),
phutil_tag(
'span',
array(
'class' => 'phabricator-menu-button-icon sprite-menu menu-icon-search',
'id' => $button_id,
),
''));
}
private function renderPhabricatorSearchMenu() {
$view = new PHUIListView();
$view->addClass('phabricator-dark-menu');
$view->addClass('phabricator-search-menu');
$search = $this->renderSearch();
if ($search) {
$view->addMenuItem($search);
}
return $view;
}
private function renderPhabricatorLogo() {
return phutil_tag(
'a',
array(
'class' => 'phabricator-main-menu-logo',
'href' => '/',
),
phutil_tag(
'span',
array(
'class' => 'sprite-menu phabricator-main-menu-logo-image',
),
''));
}
private function renderNotificationMenu() {
$user = $this->user;
require_celerity_resource('phabricator-notification-css');
require_celerity_resource('phabricator-notification-menu-css');
require_celerity_resource('sprite-menu-css');
$container_classes = array(
'sprite-menu',
'alert-notifications',
);
$message_tag = '';
$message_notification_dropdown = '';
$conpherence = 'PhabricatorApplicationConpherence';
if (PhabricatorApplication::isClassInstalled($conpherence)) {
$message_id = celerity_generate_unique_node_id();
$message_count_id = celerity_generate_unique_node_id();
$message_dropdown_id = celerity_generate_unique_node_id();
$unread_status = ConpherenceParticipationStatus::BEHIND;
$unread = id(new ConpherenceParticipantCountQuery())
->withParticipantPHIDs(array($user->getPHID()))
->withParticipationStatus($unread_status)
->execute();
$message_count_number = idx($unread, $user->getPHID(), 0);
if ($message_count_number > 999) {
$message_count_number = "\xE2\x88\x9E";
}
$message_count_tag = phutil_tag(
'span',
array(
'id' => $message_count_id,
'class' => 'phabricator-main-menu-message-count'
),
$message_count_number);
$message_icon_tag = phutil_tag(
'span',
array(
'class' => 'sprite-menu phabricator-main-menu-message-icon',
),
'');
if ($message_count_number) {
$container_classes[] = 'message-unread';
}
$message_tag = phutil_tag(
'a',
array(
'href' => '/conpherence/',
'class' => implode(' ', $container_classes),
'id' => $message_id,
),
array(
$message_icon_tag,
$message_count_tag,
));
Javelin::initBehavior(
'aphlict-dropdown',
array(
'bubbleID' => $message_id,
'countID' => $message_count_id,
'dropdownID' => $message_dropdown_id,
'loadingText' => pht('Loading...'),
'uri' => '/conpherence/panel/',
));
$message_notification_dropdown = javelin_tag(
'div',
array(
'id' => $message_dropdown_id,
'class' => 'phabricator-notification-menu',
'sigil' => 'phabricator-notification-menu',
'style' => 'display: none;',
),
'');
}
$count_id = celerity_generate_unique_node_id();
$dropdown_id = celerity_generate_unique_node_id();
$bubble_id = celerity_generate_unique_node_id();
$count_number = id(new PhabricatorFeedStoryNotification())
->countUnread($user);
if ($count_number > 999) {
$count_number = "\xE2\x88\x9E";
}
$count_tag = phutil_tag(
'span',
array(
'id' => $count_id,
'class' => 'phabricator-main-menu-alert-count'
),
$count_number);
$icon_tag = phutil_tag(
'span',
array(
'class' => 'sprite-menu phabricator-main-menu-alert-icon',
),
'');
if ($count_number) {
$container_classes[] = 'alert-unread';
}
$bubble_tag = phutil_tag(
'a',
array(
'href' => '/notification/',
'class' => implode(' ', $container_classes),
'id' => $bubble_id,
),
array($icon_tag, $count_tag));
Javelin::initBehavior(
'aphlict-dropdown',
array(
'bubbleID' => $bubble_id,
'countID' => $count_id,
'dropdownID' => $dropdown_id,
'loadingText' => pht('Loading...'),
'uri' => '/notification/panel/',
));
$notification_dropdown = javelin_tag(
'div',
array(
'id' => $dropdown_id,
'class' => 'phabricator-notification-menu',
'sigil' => 'phabricator-notification-menu',
'style' => 'display: none;',
),
'');
$dropdowns = array(
$notification_dropdown,
$message_notification_dropdown);
return array(
hsprintf('%s%s', $bubble_tag, $message_tag),
$dropdowns
);
}
private function renderMenuIcon($name) {
return phutil_tag(
'span',
array(
'class' => 'phabricator-core-menu-icon '.
'sprite-apps-large apps-'.$name,
),
'');
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jul 2, 7:09 AM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
164768
Default Alt Text
(62 KB)

Event Timeline