Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php
index f525d0ec97..72b577771f 100644
--- a/src/applications/base/PhabricatorApplication.php
+++ b/src/applications/base/PhabricatorApplication.php
@@ -1,662 +1,666 @@
<?php
/**
* @task info Application Information
* @task ui UI Integration
* @task uri URI Routing
* @task mail Email integration
* @task fact Fact Integration
* @task meta Application Management
*/
abstract class PhabricatorApplication
extends PhabricatorLiskDAO
implements
PhabricatorPolicyInterface,
PhabricatorApplicationTransactionInterface {
const GROUP_CORE = 'core';
const GROUP_UTILITIES = 'util';
const GROUP_ADMIN = 'admin';
const GROUP_DEVELOPER = 'developer';
final public static function getApplicationGroups() {
return array(
self::GROUP_CORE => pht('Core Applications'),
self::GROUP_UTILITIES => pht('Utilities'),
self::GROUP_ADMIN => pht('Administration'),
self::GROUP_DEVELOPER => pht('Developer Tools'),
);
}
final public function getApplicationName() {
return 'application';
}
final public function getTableName() {
return 'application_application';
}
final protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
final public function generatePHID() {
return $this->getPHID();
}
final public function save() {
// When "save()" is called on applications, we just return without
// actually writing anything to the database.
return $this;
}
/* -( Application Information )-------------------------------------------- */
abstract public function getName();
+ public function getMenuName() {
+ return $this->getName();
+ }
+
public function getShortDescription() {
return pht('%s Application', $this->getName());
}
final public function isInstalled() {
if (!$this->canUninstall()) {
return true;
}
$prototypes = PhabricatorEnv::getEnvConfig('phabricator.show-prototypes');
if (!$prototypes && $this->isPrototype()) {
return false;
}
$uninstalled = PhabricatorEnv::getEnvConfig(
'phabricator.uninstalled-applications');
return empty($uninstalled[get_class($this)]);
}
public function isPrototype() {
return false;
}
/**
* Return `true` if this application should never appear in application lists
* in the UI. Primarily intended for unit test applications or other
* pseudo-applications.
*
* Few applications should be unlisted. For most applications, use
* @{method:isLaunchable} to hide them from main launch views instead.
*
* @return bool True to remove application from UI lists.
*/
public function isUnlisted() {
return false;
}
/**
* Return `true` if this application is a normal application with a base
* URI and a web interface.
*
* Launchable applications can be pinned to the home page, and show up in the
* "Launcher" view of the Applications application. Making an application
* unlauncahble prevents pinning and hides it from this view.
*
* Usually, an application should be marked unlaunchable if:
*
* - it is available on every page anyway (like search); or
* - it does not have a web interface (like subscriptions); or
* - it is still pre-release and being intentionally buried.
*
* To hide applications more completely, use @{method:isUnlisted}.
*
* @return bool True if the application is launchable.
*/
public function isLaunchable() {
return true;
}
/**
* Return `true` if this application should be pinned by default.
*
* Users who have not yet set preferences see a default list of applications.
*
* @param PhabricatorUser User viewing the pinned application list.
* @return bool True if this application should be pinned by default.
*/
public function isPinnedByDefault(PhabricatorUser $viewer) {
return false;
}
/**
* Returns true if an application is first-party (developed by Phacility)
* and false otherwise.
*
* @return bool True if this application is developed by Phacility.
*/
final public function isFirstParty() {
$where = id(new ReflectionClass($this))->getFileName();
$root = phutil_get_library_root('phabricator');
if (!Filesystem::isDescendant($where, $root)) {
return false;
}
if (Filesystem::isDescendant($where, $root.'/extensions')) {
return false;
}
return true;
}
public function canUninstall() {
return true;
}
final public function getPHID() {
return 'PHID-APPS-'.get_class($this);
}
public function getTypeaheadURI() {
return $this->isLaunchable() ? $this->getBaseURI() : null;
}
public function getBaseURI() {
return null;
}
final public function getApplicationURI($path = '') {
return $this->getBaseURI().ltrim($path, '/');
}
public function getIcon() {
return 'fa-puzzle-piece';
}
public function getApplicationOrder() {
return PHP_INT_MAX;
}
public function getApplicationGroup() {
return self::GROUP_CORE;
}
public function getTitleGlyph() {
return null;
}
final public function getHelpMenuItems(PhabricatorUser $viewer) {
$items = array();
$articles = $this->getHelpDocumentationArticles($viewer);
if ($articles) {
foreach ($articles as $article) {
$item = id(new PhabricatorActionView())
->setName($article['name'])
->setHref($article['href'])
->addSigil('help-item')
->setOpenInNewWindow(true);
$items[] = $item;
}
}
$command_specs = $this->getMailCommandObjects();
if ($command_specs) {
foreach ($command_specs as $key => $spec) {
$object = $spec['object'];
$class = get_class($this);
$href = '/applications/mailcommands/'.$class.'/'.$key.'/';
$item = id(new PhabricatorActionView())
->setName($spec['name'])
->setHref($href)
->addSigil('help-item')
->setOpenInNewWindow(true);
$items[] = $item;
}
}
if ($items) {
$divider = id(new PhabricatorActionView())
->addSigil('help-item')
->setType(PhabricatorActionView::TYPE_DIVIDER);
array_unshift($items, $divider);
}
return array_values($items);
}
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array();
}
public function getOverview() {
return null;
}
public function getEventListeners() {
return array();
}
public function getRemarkupRules() {
return array();
}
public function getQuicksandURIPatternBlacklist() {
return array();
}
public function getMailCommandObjects() {
return array();
}
/* -( URI Routing )-------------------------------------------------------- */
public function getRoutes() {
return array();
}
public function getResourceRoutes() {
return array();
}
/* -( Email Integration )-------------------------------------------------- */
public function supportsEmailIntegration() {
return false;
}
final protected function getInboundEmailSupportLink() {
return PhabricatorEnv::getDoclink('Configuring Inbound Email');
}
public function getAppEmailBlurb() {
throw new PhutilMethodNotImplementedException();
}
/* -( Fact Integration )--------------------------------------------------- */
public function getFactObjectsForAnalysis() {
return array();
}
/* -( UI Integration )----------------------------------------------------- */
/**
* You can provide an optional piece of flavor text for the application. This
* is currently rendered in application launch views if the application has no
* status elements.
*
* @return string|null Flavor text.
* @task ui
*/
public function getFlavorText() {
return null;
}
/**
* Build items for the main menu.
*
* @param PhabricatorUser The viewing user.
* @param AphrontController The current controller. May be null for special
* pages like 404, exception handlers, etc.
* @return list<PHUIListItemView> List of menu items.
* @task ui
*/
public function buildMainMenuItems(
PhabricatorUser $user,
PhabricatorController $controller = null) {
return array();
}
/* -( Application Management )--------------------------------------------- */
final public static function getByClass($class_name) {
$selected = null;
$applications = self::getAllApplications();
foreach ($applications as $application) {
if (get_class($application) == $class_name) {
$selected = $application;
break;
}
}
if (!$selected) {
throw new Exception(pht("No application '%s'!", $class_name));
}
return $selected;
}
final public static function getAllApplications() {
static $applications;
if ($applications === null) {
$apps = id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setSortMethod('getApplicationOrder')
->execute();
// Reorder the applications into "application order". Notably, this
// ensures their event handlers register in application order.
$apps = mgroup($apps, 'getApplicationGroup');
$group_order = array_keys(self::getApplicationGroups());
$apps = array_select_keys($apps, $group_order) + $apps;
$apps = array_mergev($apps);
$applications = $apps;
}
return $applications;
}
final public static function getAllInstalledApplications() {
$all_applications = self::getAllApplications();
$apps = array();
foreach ($all_applications as $app) {
if (!$app->isInstalled()) {
continue;
}
$apps[] = $app;
}
return $apps;
}
/**
* Determine if an application is installed, by application class name.
*
* To check if an application is installed //and// available to a particular
* viewer, user @{method:isClassInstalledForViewer}.
*
* @param string Application class name.
* @return bool True if the class is installed.
* @task meta
*/
final public static function isClassInstalled($class) {
return self::getByClass($class)->isInstalled();
}
/**
* Determine if an application is installed and available to a viewer, by
* application class name.
*
* To check if an application is installed at all, use
* @{method:isClassInstalled}.
*
* @param string Application class name.
* @param PhabricatorUser Viewing user.
* @return bool True if the class is installed for the viewer.
* @task meta
*/
final public static function isClassInstalledForViewer(
$class,
PhabricatorUser $viewer) {
if ($viewer->isOmnipotent()) {
return true;
}
$cache = PhabricatorCaches::getRequestCache();
$viewer_fragment = $viewer->getCacheFragment();
$key = 'app.'.$class.'.installed.'.$viewer_fragment;
$result = $cache->getKey($key);
if ($result === null) {
if (!self::isClassInstalled($class)) {
$result = false;
} else {
$application = self::getByClass($class);
if (!$application->canUninstall()) {
// If the application can not be uninstalled, always allow viewers
// to see it. In particular, this allows logged-out viewers to see
// Settings and load global default settings even if the install
// does not allow public viewers.
$result = true;
} else {
$result = PhabricatorPolicyFilter::hasCapability(
$viewer,
self::getByClass($class),
PhabricatorPolicyCapability::CAN_VIEW);
}
}
$cache->setKey($key, $result);
}
return $result;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array_merge(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
),
array_keys($this->getCustomCapabilities()));
}
public function getPolicy($capability) {
$default = $this->getCustomPolicySetting($capability);
if ($default) {
return $default;
}
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return PhabricatorPolicies::getMostOpenPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return PhabricatorPolicies::POLICY_ADMIN;
default:
$spec = $this->getCustomCapabilitySpecification($capability);
return idx($spec, 'default', PhabricatorPolicies::POLICY_USER);
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
/* -( Policies )----------------------------------------------------------- */
protected function getCustomCapabilities() {
return array();
}
final private function getCustomPolicySetting($capability) {
if (!$this->isCapabilityEditable($capability)) {
return null;
}
$policy_locked = PhabricatorEnv::getEnvConfig('policy.locked');
if (isset($policy_locked[$capability])) {
return $policy_locked[$capability];
}
$config = PhabricatorEnv::getEnvConfig('phabricator.application-settings');
$app = idx($config, $this->getPHID());
if (!$app) {
return null;
}
$policy = idx($app, 'policy');
if (!$policy) {
return null;
}
return idx($policy, $capability);
}
final private function getCustomCapabilitySpecification($capability) {
$custom = $this->getCustomCapabilities();
if (!isset($custom[$capability])) {
throw new Exception(pht("Unknown capability '%s'!", $capability));
}
return $custom[$capability];
}
final public function getCapabilityLabel($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return pht('Can Use Application');
case PhabricatorPolicyCapability::CAN_EDIT:
return pht('Can Configure Application');
}
$capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
if ($capobj) {
return $capobj->getCapabilityName();
}
return null;
}
final public function isCapabilityEditable($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->canUninstall();
case PhabricatorPolicyCapability::CAN_EDIT:
return false;
default:
$spec = $this->getCustomCapabilitySpecification($capability);
return idx($spec, 'edit', true);
}
}
final public function getCapabilityCaption($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
if (!$this->canUninstall()) {
return pht(
'This application is required for Phabricator to operate, so all '.
'users must have access to it.');
} else {
return null;
}
case PhabricatorPolicyCapability::CAN_EDIT:
return null;
default:
$spec = $this->getCustomCapabilitySpecification($capability);
return idx($spec, 'caption');
}
}
final public function getCapabilityTemplatePHIDType($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
case PhabricatorPolicyCapability::CAN_EDIT:
return null;
}
$spec = $this->getCustomCapabilitySpecification($capability);
return idx($spec, 'template');
}
final public function getDefaultObjectTypePolicyMap() {
$map = array();
foreach ($this->getCustomCapabilities() as $capability => $spec) {
if (empty($spec['template'])) {
continue;
}
if (empty($spec['capability'])) {
continue;
}
$default = $this->getPolicy($capability);
$map[$spec['template']][$spec['capability']] = $default;
}
return $map;
}
public function getApplicationSearchDocumentTypes() {
return array();
}
protected function getEditRoutePattern($base = null) {
return $base.'(?:'.
'(?P<id>[0-9]\d*)/)?'.
'(?:'.
'(?:'.
'(?P<editAction>parameters|nodefault|nocreate|nomanage|comment)/'.
'|'.
'(?:form/(?P<formKey>[^/]+)/)?(?:page/(?P<pageKey>[^/]+)/)?'.
')'.
')?';
}
protected function getQueryRoutePattern($base = null) {
return $base.'(?:query/(?P<queryKey>[^/]+)/)?';
}
protected function getProfileMenuRouting($controller) {
$edit_route = $this->getEditRoutePattern();
$mode_route = '(?P<itemEditMode>global|custom)/';
return array(
'(?P<itemAction>view)/(?P<itemID>[^/]+)/' => $controller,
'(?P<itemAction>hide)/(?P<itemID>[^/]+)/' => $controller,
'(?P<itemAction>default)/(?P<itemID>[^/]+)/' => $controller,
'(?P<itemAction>configure)/' => $controller,
'(?P<itemAction>configure)/'.$mode_route => $controller,
'(?P<itemAction>reorder)/'.$mode_route => $controller,
'(?P<itemAction>edit)/'.$edit_route => $controller,
'(?P<itemAction>new)/'.$mode_route.'(?<itemKey>[^/]+)/'.$edit_route
=> $controller,
'(?P<itemAction>builtin)/(?<itemID>[^/]+)/'.$edit_route
=> $controller,
);
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
public function getApplicationTransactionEditor() {
return new PhabricatorApplicationEditor();
}
public function getApplicationTransactionObject() {
return $this;
}
public function getApplicationTransactionTemplate() {
return new PhabricatorApplicationApplicationTransaction();
}
public function willRenderTimeline(
PhabricatorApplicationTransactionView $timeline,
AphrontRequest $request) {
return $timeline;
}
}
diff --git a/src/applications/differential/application/PhabricatorDifferentialApplication.php b/src/applications/differential/application/PhabricatorDifferentialApplication.php
index e259c2f112..1c8926f585 100644
--- a/src/applications/differential/application/PhabricatorDifferentialApplication.php
+++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php
@@ -1,146 +1,150 @@
<?php
final class PhabricatorDifferentialApplication extends PhabricatorApplication {
public function getBaseURI() {
return '/differential/';
}
public function getName() {
return pht('Differential');
}
+ public function getMenuName() {
+ return pht('Code Review');
+ }
+
public function getShortDescription() {
- return pht('Review Code');
+ return pht('Pre-Commit Review');
}
public function getIcon() {
return 'fa-cog';
}
public function isPinnedByDefault(PhabricatorUser $viewer) {
return true;
}
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array(
array(
'name' => pht('Differential User Guide'),
'href' => PhabricatorEnv::getDoclink('Differential User Guide'),
),
);
}
public function getFactObjectsForAnalysis() {
return array(
new DifferentialRevision(),
);
}
public function getTitleGlyph() {
return "\xE2\x9A\x99";
}
public function getOverview() {
return pht(
'Differential is a **code review application** which allows '.
'engineers to review, discuss and approve changes to software.');
}
public function getRoutes() {
return array(
'/D(?P<id>[1-9]\d*)' => 'DifferentialRevisionViewController',
'/differential/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?'
=> 'DifferentialRevisionListController',
'diff/' => array(
'(?P<id>[1-9]\d*)/' => 'DifferentialDiffViewController',
'create/' => 'DifferentialDiffCreateController',
),
'changeset/' => 'DifferentialChangesetViewController',
'revision/' => array(
$this->getEditRoutePattern('edit/')
=> 'DifferentialRevisionEditController',
$this->getEditRoutePattern('attach/(?P<diffID>[^/]+)/to/')
=> 'DifferentialRevisionEditController',
'closedetails/(?P<phid>[^/]+)/'
=> 'DifferentialRevisionCloseDetailsController',
'update/(?P<revisionID>[1-9]\d*)/'
=> 'DifferentialDiffCreateController',
'operation/(?P<id>[1-9]\d*)/'
=> 'DifferentialRevisionOperationController',
'inlines/(?P<id>[1-9]\d*)/'
=> 'DifferentialRevisionInlinesController',
),
'comment/' => array(
'preview/(?P<id>[1-9]\d*)/' => 'DifferentialCommentPreviewController',
'save/(?P<id>[1-9]\d*)/' => 'DifferentialCommentSaveController',
'inline/' => array(
'preview/(?P<id>[1-9]\d*)/'
=> 'DifferentialInlineCommentPreviewController',
'edit/(?P<id>[1-9]\d*)/'
=> 'DifferentialInlineCommentEditController',
),
),
'preview/' => 'PhabricatorMarkupPreviewController',
),
);
}
public function getApplicationOrder() {
return 0.100;
}
public function getRemarkupRules() {
return array(
new DifferentialRemarkupRule(),
);
}
public function supportsEmailIntegration() {
return true;
}
public function getAppEmailBlurb() {
return pht(
'Send email to these addresses to create revisions. The body of the '.
'message and / or one or more attachments should be the output of a '.
'"diff" command. %s',
phutil_tag(
'a',
array(
'href' => $this->getInboundEmailSupportLink(),
),
pht('Learn More')));
}
protected function getCustomCapabilities() {
return array(
DifferentialDefaultViewCapability::CAPABILITY => array(
'caption' => pht('Default view policy for newly created revisions.'),
'template' => DifferentialRevisionPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_VIEW,
),
);
}
public function getMailCommandObjects() {
return array(
'revision' => array(
'name' => pht('Email Commands: Revisions'),
'header' => pht('Interacting with Differential Revisions'),
'object' => new DifferentialRevision(),
'summary' => pht(
'This page documents the commands you can use to interact with '.
'revisions in Differential.'),
),
);
}
public function getApplicationSearchDocumentTypes() {
return array(
DifferentialRevisionPHIDType::TYPECONST,
);
}
}
diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php
index b00fcce77f..cf9c14aa8b 100644
--- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php
+++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php
@@ -1,194 +1,198 @@
<?php
final class PhabricatorDiffusionApplication extends PhabricatorApplication {
public function getName() {
return pht('Diffusion');
}
+ public function getMenuName() {
+ return pht('Repositories');
+ }
+
public function getShortDescription() {
return pht('Host and Browse Repositories');
}
public function getBaseURI() {
return '/diffusion/';
}
public function getIcon() {
return 'fa-code';
}
public function isPinnedByDefault(PhabricatorUser $viewer) {
return true;
}
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array(
array(
'name' => pht('Diffusion User Guide'),
'href' => PhabricatorEnv::getDoclink('Diffusion User Guide'),
),
array(
'name' => pht('Audit User Guide'),
'href' => PhabricatorEnv::getDoclink('Audit User Guide'),
),
);
}
public function getFactObjectsForAnalysis() {
return array(
new PhabricatorRepositoryCommit(),
);
}
public function getRemarkupRules() {
return array(
new DiffusionCommitRemarkupRule(),
new DiffusionRepositoryRemarkupRule(),
new DiffusionRepositoryByIDRemarkupRule(),
);
}
public function getRoutes() {
$repository_routes = array(
'/' => array(
'' => 'DiffusionRepositoryController',
'repository/(?P<dblob>.*)' => 'DiffusionRepositoryController',
'change/(?P<dblob>.*)' => 'DiffusionChangeController',
'clone/' => 'DiffusionCloneController',
'history/(?P<dblob>.*)' => 'DiffusionHistoryController',
'graph/(?P<dblob>.*)' => 'DiffusionGraphController',
'browse/(?P<dblob>.*)' => 'DiffusionBrowseController',
'lastmodified/(?P<dblob>.*)' => 'DiffusionLastModifiedController',
'diff/' => 'DiffusionDiffController',
'tags/(?P<dblob>.*)' => 'DiffusionTagListController',
'branches/(?P<dblob>.*)' => 'DiffusionBranchTableController',
'refs/(?P<dblob>.*)' => 'DiffusionRefTableController',
'lint/(?P<dblob>.*)' => 'DiffusionLintController',
'commit/(?P<commit>[a-z0-9]+)/branches/'
=> 'DiffusionCommitBranchesController',
'commit/(?P<commit>[a-z0-9]+)/tags/'
=> 'DiffusionCommitTagsController',
'compare/' => 'DiffusionCompareController',
'manage/(?:(?P<panel>[^/]+)/)?'
=> 'DiffusionRepositoryManagePanelsController',
'uri/' => array(
'view/(?P<id>[0-9]\d*)/' => 'DiffusionRepositoryURIViewController',
'disable/(?P<id>[0-9]\d*)/'
=> 'DiffusionRepositoryURIDisableController',
$this->getEditRoutePattern('edit/')
=> 'DiffusionRepositoryURIEditController',
'credential/(?P<id>[0-9]\d*)/(?P<action>edit|remove)/'
=> 'DiffusionRepositoryURICredentialController',
),
'edit/' => array(
'activate/' => 'DiffusionRepositoryEditActivateController',
'dangerous/' => 'DiffusionRepositoryEditDangerousController',
'delete/' => 'DiffusionRepositoryEditDeleteController',
'update/' => 'DiffusionRepositoryEditUpdateController',
'testautomation/' => 'DiffusionRepositoryTestAutomationController',
),
'pathtree/(?P<dblob>.*)' => 'DiffusionPathTreeController',
),
// NOTE: This must come after the rules above; it just gives us a
// catch-all for serving repositories over HTTP. We must accept requests
// without the trailing "/" because SVN commands don't necessarily
// include it.
'(?:/.*)?' => 'DiffusionRepositoryDefaultController',
);
return array(
'/(?:'.
'r(?P<repositoryCallsign>[A-Z]+)'.
'|'.
'R(?P<repositoryID>[1-9]\d*):'.
')(?P<commit>[a-f0-9]+)'
=> 'DiffusionCommitController',
'/source/(?P<repositoryShortName>[^/]+)'
=> $repository_routes,
'/diffusion/' => array(
$this->getQueryRoutePattern()
=> 'DiffusionRepositoryListController',
$this->getEditRoutePattern('edit/') =>
'DiffusionRepositoryEditController',
'pushlog/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'DiffusionPushLogListController',
'view/(?P<id>\d+)/' => 'DiffusionPushEventViewController',
),
'(?P<repositoryCallsign>[A-Z]+)' => $repository_routes,
'(?P<repositoryID>[1-9]\d*)' => $repository_routes,
'inline/' => array(
'edit/(?P<phid>[^/]+)/' => 'DiffusionInlineCommentController',
'preview/(?P<phid>[^/]+)/'
=> 'DiffusionInlineCommentPreviewController',
),
'services/' => array(
'path/' => array(
'complete/' => 'DiffusionPathCompleteController',
'validate/' => 'DiffusionPathValidateController',
),
),
'symbol/(?P<name>[^/]+)/' => 'DiffusionSymbolController',
'external/' => 'DiffusionExternalController',
'lint/' => 'DiffusionLintController',
'commit/' => array(
$this->getQueryRoutePattern() =>
'DiffusionCommitListController',
$this->getEditRoutePattern('edit/') =>
'DiffusionCommitEditController',
),
'picture/(?P<id>[0-9]\d*)/'
=> 'DiffusionRepositoryProfilePictureController',
),
);
}
public function getApplicationOrder() {
return 0.120;
}
protected function getCustomCapabilities() {
return array(
DiffusionDefaultViewCapability::CAPABILITY => array(
'template' => PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_VIEW,
),
DiffusionDefaultEditCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_ADMIN,
'template' => PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
),
DiffusionDefaultPushCapability::CAPABILITY => array(
'template' => PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
),
DiffusionCreateRepositoriesCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_ADMIN,
),
);
}
public function getMailCommandObjects() {
return array(
'commit' => array(
'name' => pht('Email Commands: Commits'),
'header' => pht('Interacting with Commits'),
'object' => new PhabricatorRepositoryCommit(),
'summary' => pht(
'This page documents the commands you can use to interact with '.
'commits and audits in Diffusion.'),
),
);
}
public function getApplicationSearchDocumentTypes() {
return array(
PhabricatorRepositoryCommitPHIDType::TYPECONST,
);
}
}
diff --git a/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php b/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php
index cbfe62aaa6..e380af2b6a 100644
--- a/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php
+++ b/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php
@@ -1,80 +1,80 @@
<?php
final class PhabricatorHomeProfileMenuEngine
extends PhabricatorProfileMenuEngine {
protected function isMenuEngineConfigurable() {
return true;
}
public function getItemURI($path) {
return "/home/menu/{$path}";
}
protected function buildItemViewContent(
PhabricatorProfileMenuItemConfiguration $item) {
$viewer = $this->getViewer();
// Add content to the document so that you can drag-and-drop files onto
// the home page or any home dashboard to upload them.
$upload = id(new PhabricatorGlobalUploadTargetView())
->setUser($viewer);
$content = parent::buildItemViewContent($item);
return array(
$content,
$upload,
);
}
protected function getBuiltinProfileItems($object) {
$viewer = $this->getViewer();
$items = array();
$custom_phid = $this->getCustomPHID();
$applications = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withInstalled(true)
->withUnlisted(false)
->withLaunchable(true)
->execute();
// Default Home Dashboard
$items[] = $this->newItem()
->setBuiltinKey(PhabricatorHomeConstants::ITEM_HOME)
->setMenuItemKey(PhabricatorHomeProfileMenuItem::MENUITEMKEY);
$items[] = $this->newItem()
->setBuiltinKey(PhabricatorHomeConstants::ITEM_APPS_LABEL)
->setMenuItemKey(PhabricatorLabelProfileMenuItem::MENUITEMKEY)
- ->setMenuItemProperties(array('name' => pht('Applications')));
+ ->setMenuItemProperties(array('name' => pht('Favorites')));
foreach ($applications as $application) {
if (!$application->isPinnedByDefault($viewer)) {
continue;
}
$properties = array(
'name' => '',
'application' => $application->getPHID(),
);
$items[] = $this->newItem()
->setBuiltinKey($application->getPHID())
->setMenuItemKey(PhabricatorApplicationProfileMenuItem::MENUITEMKEY)
->setMenuItemProperties($properties);
}
// Hotlink to More Applications Launcher...
$items[] = $this->newItem()
->setBuiltinKey(PhabricatorHomeConstants::ITEM_LAUNCHER)
->setMenuItemKey(PhabricatorHomeLauncherProfileMenuItem::MENUITEMKEY);
$items[] = $this->newManageItem();
return $items;
}
}
diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php
index 6cb9626d5a..3076354599 100644
--- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php
+++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php
@@ -1,118 +1,122 @@
<?php
final class PhabricatorManiphestApplication extends PhabricatorApplication {
public function getName() {
return pht('Maniphest');
}
+ public function getMenuName() {
+ return pht('Tasks');
+ }
+
public function getShortDescription() {
return pht('Tasks and Bugs');
}
public function getBaseURI() {
return '/maniphest/';
}
public function getIcon() {
return 'fa-anchor';
}
public function getTitleGlyph() {
return "\xE2\x9A\x93";
}
public function isPinnedByDefault(PhabricatorUser $viewer) {
return true;
}
public function getApplicationOrder() {
return 0.110;
}
public function getFactObjectsForAnalysis() {
return array(
new ManiphestTask(),
);
}
public function getRemarkupRules() {
return array(
new ManiphestRemarkupRule(),
);
}
public function getRoutes() {
return array(
'/T(?P<id>[1-9]\d*)' => 'ManiphestTaskDetailController',
'/maniphest/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'ManiphestTaskListController',
'report/(?:(?P<view>\w+)/)?' => 'ManiphestReportController',
'batch/' => 'ManiphestBatchEditController',
'task/' => array(
$this->getEditRoutePattern('edit/')
=> 'ManiphestTaskEditController',
),
'export/(?P<key>[^/]+)/' => 'ManiphestExportController',
'subpriority/' => 'ManiphestSubpriorityController',
),
);
}
public function supportsEmailIntegration() {
return true;
}
public function getAppEmailBlurb() {
return pht(
'Send email to these addresses to create tasks. %s',
phutil_tag(
'a',
array(
'href' => $this->getInboundEmailSupportLink(),
),
pht('Learn More')));
}
protected function getCustomCapabilities() {
return array(
ManiphestDefaultViewCapability::CAPABILITY => array(
'caption' => pht('Default view policy for newly created tasks.'),
'template' => ManiphestTaskPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_VIEW,
),
ManiphestDefaultEditCapability::CAPABILITY => array(
'caption' => pht('Default edit policy for newly created tasks.'),
'template' => ManiphestTaskPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
),
ManiphestEditStatusCapability::CAPABILITY => array(),
ManiphestEditAssignCapability::CAPABILITY => array(),
ManiphestEditPoliciesCapability::CAPABILITY => array(),
ManiphestEditPriorityCapability::CAPABILITY => array(),
ManiphestEditProjectsCapability::CAPABILITY => array(),
ManiphestBulkEditCapability::CAPABILITY => array(),
);
}
public function getMailCommandObjects() {
return array(
'task' => array(
'name' => pht('Email Commands: Tasks'),
'header' => pht('Interacting with Maniphest Tasks'),
'object' => new ManiphestTask(),
'summary' => pht(
'This page documents the commands you can use to interact with '.
'tasks in Maniphest. These commands work when creating new tasks '.
'via email and when replying to existing tasks.'),
),
);
}
public function getApplicationSearchDocumentTypes() {
return array(
ManiphestTaskPHIDType::TYPECONST,
);
}
}
diff --git a/src/applications/phame/application/PhabricatorPhameApplication.php b/src/applications/phame/application/PhabricatorPhameApplication.php
index 677872ba1e..f9ee2831b2 100644
--- a/src/applications/phame/application/PhabricatorPhameApplication.php
+++ b/src/applications/phame/application/PhabricatorPhameApplication.php
@@ -1,122 +1,126 @@
<?php
final class PhabricatorPhameApplication extends PhabricatorApplication {
public function getName() {
return pht('Phame');
}
+ public function getMenuName() {
+ return pht('Blogs');
+ }
+
public function getBaseURI() {
return '/phame/';
}
public function getIcon() {
return 'fa-feed';
}
public function getShortDescription() {
- return pht('Blog');
+ return pht('Internal and External Blogs');
}
public function getTitleGlyph() {
return "\xe2\x9c\xa9";
}
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array(
array(
'name' => pht('Phame User Guide'),
'href' => PhabricatorEnv::getDoclink('Phame User Guide'),
),
);
}
public function getRoutes() {
return array(
'/J(?P<id>[1-9]\d*)' => 'PhamePostViewController',
'/phame/' => array(
'' => 'PhameHomeController',
// NOTE: The live routes include an initial "/", so leave it off
// this route.
'(?P<live>live)/(?P<blogID>\d+)' => $this->getLiveRoutes(),
'post/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhamePostListController',
'blogger/(?P<bloggername>[\w\.-_]+)/' => 'PhamePostListController',
$this->getEditRoutePattern('edit/')
=> 'PhamePostEditController',
'history/(?P<id>\d+)/' => 'PhamePostHistoryController',
'view/(?P<id>\d+)/(?:(?P<slug>[^/]+)/)?' => 'PhamePostViewController',
'(?P<action>publish|unpublish)/(?P<id>\d+)/'
=> 'PhamePostPublishController',
'preview/(?P<id>\d+)/' => 'PhamePostPreviewController',
'preview/' => 'PhabricatorMarkupPreviewController',
'move/(?P<id>\d+)/' => 'PhamePostMoveController',
'archive/(?P<id>\d+)/' => 'PhamePostArchiveController',
'header/(?P<id>[1-9]\d*)/' => 'PhamePostHeaderPictureController',
),
'blog/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhameBlogListController',
'archive/(?P<id>[^/]+)/' => 'PhameBlogArchiveController',
$this->getEditRoutePattern('edit/')
=> 'PhameBlogEditController',
'view/(?P<blogID>\d+)/' => 'PhameBlogViewController',
'manage/(?P<id>[^/]+)/' => 'PhameBlogManageController',
'feed/(?P<id>[^/]+)/' => 'PhameBlogFeedController',
'picture/(?P<id>[1-9]\d*)/' => 'PhameBlogProfilePictureController',
'header/(?P<id>[1-9]\d*)/' => 'PhameBlogHeaderPictureController',
),
) + $this->getResourceSubroutes(),
);
}
public function getResourceRoutes() {
return array(
'/phame/' => $this->getResourceSubroutes(),
);
}
private function getResourceSubroutes() {
return array(
'r/(?P<id>\d+)/(?P<hash>[^/]+)/(?P<name>.*)' =>
'PhameResourceController',
);
}
public function getBlogRoutes() {
return $this->getLiveRoutes();
}
private function getLiveRoutes() {
return array(
'/' => array(
'' => 'PhameBlogViewController',
'post/(?P<id>\d+)/(?:(?P<slug>[^/]+)/)?' => 'PhamePostViewController',
),
);
}
public function getQuicksandURIPatternBlacklist() {
return array(
'/phame/live/.*',
);
}
public function getRemarkupRules() {
return array(
new PhamePostRemarkupRule(),
);
}
protected function getCustomCapabilities() {
return array(
PhameBlogCreateCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_USER,
'caption' => pht('Default create policy for blogs.'),
),
);
}
}
diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php
index 4d80dd12ae..4afaeba263 100644
--- a/src/applications/pholio/application/PhabricatorPholioApplication.php
+++ b/src/applications/pholio/application/PhabricatorPholioApplication.php
@@ -1,88 +1,92 @@
<?php
final class PhabricatorPholioApplication extends PhabricatorApplication {
public function getName() {
return pht('Pholio');
}
+ public function getMenuName() {
+ return pht('Design Review');
+ }
+
public function getBaseURI() {
return '/pholio/';
}
public function getShortDescription() {
return pht('Review Mocks and Design');
}
public function getIcon() {
return 'fa-camera-retro';
}
public function getTitleGlyph() {
return "\xE2\x9D\xA6";
}
public function getFlavorText() {
return pht('Things before they were cool.');
}
public function getRemarkupRules() {
return array(
new PholioRemarkupRule(),
);
}
public function getRoutes() {
return array(
'/M(?P<id>[1-9]\d*)(?:/(?P<imageID>\d+)/)?' => 'PholioMockViewController',
'/pholio/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PholioMockListController',
'new/' => 'PholioMockEditController',
'create/' => 'PholioMockEditController',
'edit/(?P<id>\d+)/' => 'PholioMockEditController',
'archive/(?P<id>\d+)/' => 'PholioMockArchiveController',
'comment/(?P<id>\d+)/' => 'PholioMockCommentController',
'inline/' => array(
'(?:(?P<id>\d+)/)?' => 'PholioInlineController',
'list/(?P<id>\d+)/' => 'PholioInlineListController',
),
'image/' => array(
'upload/' => 'PholioImageUploadController',
),
),
);
}
protected function getCustomCapabilities() {
return array(
PholioDefaultViewCapability::CAPABILITY => array(
'template' => PholioMockPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_VIEW,
),
PholioDefaultEditCapability::CAPABILITY => array(
'template' => PholioMockPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
),
);
}
public function getMailCommandObjects() {
return array(
'mock' => array(
'name' => pht('Email Commands: Mocks'),
'header' => pht('Interacting with Pholio Mocks'),
'object' => new PholioMock(),
'summary' => pht(
'This page documents the commands you can use to interact with '.
'mocks in Pholio.'),
),
);
}
public function getApplicationSearchDocumentTypes() {
return array(
PholioMockPHIDType::TYPECONST,
);
}
}
diff --git a/src/applications/phriction/application/PhabricatorPhrictionApplication.php b/src/applications/phriction/application/PhabricatorPhrictionApplication.php
index d0eb46a069..1b06fd197c 100644
--- a/src/applications/phriction/application/PhabricatorPhrictionApplication.php
+++ b/src/applications/phriction/application/PhabricatorPhrictionApplication.php
@@ -1,78 +1,82 @@
<?php
final class PhabricatorPhrictionApplication extends PhabricatorApplication {
public function getName() {
return pht('Phriction');
}
- public function getShortDescription() {
+ public function getMenuName() {
return pht('Wiki');
}
+ public function getShortDescription() {
+ return pht('Wiki Documents');
+ }
+
public function getBaseURI() {
return '/w/';
}
public function getIcon() {
return 'fa-book';
}
public function isPinnedByDefault(PhabricatorUser $viewer) {
return true;
}
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array(
array(
'name' => pht('Phriction User Guide'),
'href' => PhabricatorEnv::getDoclink('Phriction User Guide'),
),
);
}
public function getTitleGlyph() {
return "\xE2\x9A\xA1";
}
public function getRemarkupRules() {
return array(
new PhrictionRemarkupRule(),
);
}
public function getRoutes() {
return array(
// Match "/w/" with slug "/".
'/w(?P<slug>/)' => 'PhrictionDocumentController',
// Match "/w/x/y/z/" with slug "x/y/z/".
'/w/(?P<slug>.+/)' => 'PhrictionDocumentController',
'/phriction/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhrictionListController',
'history(?P<slug>/)' => 'PhrictionHistoryController',
'history/(?P<slug>.+/)' => 'PhrictionHistoryController',
'edit/(?:(?P<id>[1-9]\d*)/)?' => 'PhrictionEditController',
'delete/(?P<id>[1-9]\d*)/' => 'PhrictionDeleteController',
'new/' => 'PhrictionNewController',
'move/(?P<id>[1-9]\d*)/' => 'PhrictionMoveController',
'preview/(?P<slug>.*/)' => 'PhrictionMarkupPreviewController',
'diff/(?P<id>[1-9]\d*)/' => 'PhrictionDiffController',
),
);
}
public function getApplicationOrder() {
return 0.140;
}
public function getApplicationSearchDocumentTypes() {
return array(
PhrictionDocumentPHIDType::TYPECONST,
);
}
}
diff --git a/src/applications/search/menuitem/PhabricatorApplicationProfileMenuItem.php b/src/applications/search/menuitem/PhabricatorApplicationProfileMenuItem.php
index aa42d56cfb..40275a8d7a 100644
--- a/src/applications/search/menuitem/PhabricatorApplicationProfileMenuItem.php
+++ b/src/applications/search/menuitem/PhabricatorApplicationProfileMenuItem.php
@@ -1,147 +1,147 @@
<?php
final class PhabricatorApplicationProfileMenuItem
extends PhabricatorProfileMenuItem {
const MENUITEMKEY = 'application';
const FIELD_APPLICATION = 'application';
public function getMenuItemTypeIcon() {
return 'fa-globe';
}
public function getMenuItemTypeName() {
return pht('Application');
}
public function canAddToObject($object) {
return true;
}
public function getDisplayName(
PhabricatorProfileMenuItemConfiguration $config) {
$application = $this->getApplication($config);
if (!$application) {
return pht('(Restricted/Invalid Application)');
}
$name = $this->getName($config);
if (strlen($name)) {
return $name;
}
- return $application->getName();
+ return $application->getMenuName();
}
public function buildEditEngineFields(
PhabricatorProfileMenuItemConfiguration $config) {
return array(
id(new PhabricatorDatasourceEditField())
->setKey(self::FIELD_APPLICATION)
->setLabel(pht('Application'))
->setDatasource(new PhabricatorApplicationDatasource())
->setIsRequired(true)
->setSingleValue($config->getMenuItemProperty('application')),
id(new PhabricatorTextEditField())
->setKey('name')
->setLabel(pht('Name'))
->setValue($this->getName($config)),
);
}
private function getName(
PhabricatorProfileMenuItemConfiguration $config) {
return $config->getMenuItemProperty('name');
}
private function getApplication(
PhabricatorProfileMenuItemConfiguration $config) {
$viewer = $this->getViewer();
$phid = $config->getMenuItemProperty('application');
$apps = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withPHIDs(array($phid))
->execute();
return head($apps);
}
protected function newNavigationMenuItems(
PhabricatorProfileMenuItemConfiguration $config) {
$viewer = $this->getViewer();
$app = $this->getApplication($config);
if (!$app) {
return array();
}
$is_installed = PhabricatorApplication::isClassInstalledForViewer(
get_class($app),
$viewer);
if (!$is_installed) {
return array();
}
$item = $this->newItem()
->setHref($app->getApplicationURI())
->setName($this->getDisplayName($config))
->setIcon($app->getIcon());
// Don't show tooltip if they've set a custom name
$name = $config->getMenuItemProperty('name');
if (!strlen($name)) {
$item->setTooltip($app->getShortDescription());
}
return array(
$item,
);
}
public function validateTransactions(
PhabricatorProfileMenuItemConfiguration $config,
$field_key,
$value,
array $xactions) {
$viewer = $this->getViewer();
$errors = array();
if ($field_key == self::FIELD_APPLICATION) {
if ($this->isEmptyTransaction($value, $xactions)) {
$errors[] = $this->newRequiredError(
pht('You must choose an application.'),
$field_key);
}
foreach ($xactions as $xaction) {
$new = $xaction['new'];
if (!$new) {
continue;
}
if ($new === $value) {
continue;
}
$applications = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withPHIDs(array($new))
->execute();
if (!$applications) {
$errors[] = $this->newInvalidError(
pht(
'Application "%s" is not a valid application which you have '.
'permission to see.',
$new),
$xaction['xaction']);
}
}
}
return $errors;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 24, 12:13 AM (22 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
182432
Default Alt Text
(50 KB)

Event Timeline