Page MenuHomePhabricator

No OneTemporary

diff --git a/src/applications/project/application/PhabricatorProjectApplication.php b/src/applications/project/application/PhabricatorProjectApplication.php
index 0f5f90a737..2d00c4c90c 100644
--- a/src/applications/project/application/PhabricatorProjectApplication.php
+++ b/src/applications/project/application/PhabricatorProjectApplication.php
@@ -1,152 +1,150 @@
<?php
final class PhabricatorProjectApplication extends PhabricatorApplication {
public function getName() {
return pht('Projects');
}
public function getShortDescription() {
return pht('Get Organized');
}
public function isPinnedByDefault(PhabricatorUser $viewer) {
return true;
}
public function getBaseURI() {
return '/project/';
}
public function getIcon() {
return 'fa-briefcase';
}
public function getFlavorText() {
return pht('Group stuff into big piles.');
}
public function getRemarkupRules() {
return array(
new ProjectRemarkupRule(),
);
}
public function getEventListeners() {
return array(
new PhabricatorProjectUIEventListener(),
);
}
public function getRoutes() {
return array(
'/project/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorProjectListController',
'filter/(?P<filter>[^/]+)/' => 'PhabricatorProjectListController',
'archive/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectArchiveController',
'lock/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectLockController',
'members/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectMembersViewController',
'members/(?P<id>[1-9]\d*)/add/'
=> 'PhabricatorProjectMembersAddController',
'(?P<type>members|watchers)/(?P<id>[1-9]\d*)/remove/'
=> 'PhabricatorProjectMembersRemoveController',
'profile/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectProfileController',
'view/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectViewController',
'picture/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectEditPictureController',
$this->getEditRoutePattern('edit/')
=> 'PhabricatorProjectEditController',
'(?P<projectID>[1-9]\d*)/panel/'
=> $this->getPanelRouting('PhabricatorProjectPanelController'),
'subprojects/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectSubprojectsController',
- 'milestones/(?P<id>[1-9]\d*)/'
- => 'PhabricatorProjectMilestonesController',
'board/(?P<id>[1-9]\d*)/'.
'(?P<filter>filter/)?'.
'(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhabricatorProjectBoardViewController',
'move/(?P<id>[1-9]\d*)/' => 'PhabricatorProjectMoveController',
'cover/' => 'PhabricatorProjectCoverController',
'board/(?P<projectID>[1-9]\d*)/' => array(
'edit/(?:(?P<id>\d+)/)?'
=> 'PhabricatorProjectColumnEditController',
'hide/(?:(?P<id>\d+)/)?'
=> 'PhabricatorProjectColumnHideController',
'column/(?:(?P<id>\d+)/)?'
=> 'PhabricatorProjectColumnDetailController',
'import/'
=> 'PhabricatorProjectBoardImportController',
'reorder/'
=> 'PhabricatorProjectBoardReorderController',
'disable/'
=> 'PhabricatorProjectBoardDisableController',
),
'update/(?P<id>[1-9]\d*)/(?P<action>[^/]+)/'
=> 'PhabricatorProjectUpdateController',
'manage/(?P<id>[1-9]\d*)/' => 'PhabricatorProjectManageController',
'(?P<action>watch|unwatch)/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectWatchController',
'silence/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectSilenceController',
'warning/(?P<id>[1-9]\d*)/'
=> 'PhabricatorProjectSubprojectWarningController',
),
'/tag/' => array(
'(?P<slug>[^/]+)/' => 'PhabricatorProjectViewController',
'(?P<slug>[^/]+)/board/' => 'PhabricatorProjectBoardViewController',
),
);
}
public function getQuickCreateItems(PhabricatorUser $viewer) {
return id(new PhabricatorProjectEditEngine())
->setViewer($viewer)
->loadQuickCreateItems();
}
protected function getCustomCapabilities() {
return array(
ProjectCreateProjectsCapability::CAPABILITY => array(),
ProjectCanLockProjectsCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_ADMIN,
),
ProjectDefaultViewCapability::CAPABILITY => array(
'caption' => pht('Default view policy for newly created projects.'),
'template' => PhabricatorProjectProjectPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_VIEW,
),
ProjectDefaultEditCapability::CAPABILITY => array(
'caption' => pht('Default edit policy for newly created projects.'),
'template' => PhabricatorProjectProjectPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
),
ProjectDefaultJoinCapability::CAPABILITY => array(
'caption' => pht('Default join policy for newly created projects.'),
'template' => PhabricatorProjectProjectPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_JOIN,
),
);
}
public function getApplicationSearchDocumentTypes() {
return array(
PhabricatorProjectProjectPHIDType::TYPECONST,
);
}
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array(
array(
'name' => pht('Projects User Guide'),
'href' => PhabricatorEnv::getDoclink('Projects User Guide'),
),
);
}
}
diff --git a/src/applications/project/engine/PhabricatorProjectEditEngine.php b/src/applications/project/engine/PhabricatorProjectEditEngine.php
index 54144cbbb5..71f91b7bc1 100644
--- a/src/applications/project/engine/PhabricatorProjectEditEngine.php
+++ b/src/applications/project/engine/PhabricatorProjectEditEngine.php
@@ -1,291 +1,287 @@
<?php
final class PhabricatorProjectEditEngine
extends PhabricatorEditEngine {
const ENGINECONST = 'projects.project';
private $parentProject;
private $milestoneProject;
public function setParentProject(PhabricatorProject $parent_project) {
$this->parentProject = $parent_project;
return $this;
}
public function getParentProject() {
return $this->parentProject;
}
public function setMilestoneProject(PhabricatorProject $milestone_project) {
$this->milestoneProject = $milestone_project;
return $this;
}
public function getMilestoneProject() {
return $this->milestoneProject;
}
public function getEngineName() {
return pht('Projects');
}
public function getSummaryHeader() {
return pht('Configure Project Forms');
}
public function getSummaryText() {
return pht('Configure forms for creating projects.');
}
public function getEngineApplicationClass() {
return 'PhabricatorProjectApplication';
}
protected function newEditableObject() {
$project = PhabricatorProject::initializeNewProject($this->getViewer());
$milestone = $this->getMilestoneProject();
if ($milestone) {
$default_name = pht(
'Milestone %s',
new PhutilNumber($milestone->loadNextMilestoneNumber()));
$project->setName($default_name);
}
return $project;
}
protected function newObjectQuery() {
return id(new PhabricatorProjectQuery())
->needSlugs(true);
}
protected function getObjectCreateTitleText($object) {
return pht('Create New Project');
}
protected function getObjectEditTitleText($object) {
return pht('Edit %s', $object->getName());
}
protected function getObjectEditShortText($object) {
return $object->getName();
}
protected function getObjectCreateShortText() {
return pht('Create Project');
}
protected function getObjectViewURI($object) {
if ($this->getIsCreate()) {
return $object->getURI();
} else {
$id = $object->getID();
return "/project/manage/{$id}/";
}
}
protected function getObjectCreateCancelURI($object) {
$parent = $this->getParentProject();
- if ($parent) {
- $id = $parent->getID();
- return "/project/subprojects/{$id}/";
- }
-
$milestone = $this->getMilestoneProject();
- if ($milestone) {
- $id = $milestone->getID();
- return "/project/milestones/{$id}/";
+
+ if ($parent || $milestone) {
+ $id = nonempty($parent, $milestone)->getID();
+ return "/project/subprojects/{$id}/";
}
return parent::getObjectCreateCancelURI($object);
}
protected function getCreateNewObjectPolicy() {
return $this->getApplication()->getPolicy(
ProjectCreateProjectsCapability::CAPABILITY);
}
protected function willConfigureFields($object, array $fields) {
$is_milestone = ($this->getMilestoneProject() || $object->isMilestone());
$unavailable = array(
PhabricatorTransactions::TYPE_VIEW_POLICY,
PhabricatorTransactions::TYPE_EDIT_POLICY,
PhabricatorTransactions::TYPE_JOIN_POLICY,
PhabricatorProjectTransaction::TYPE_ICON,
PhabricatorProjectTransaction::TYPE_COLOR,
);
$unavailable = array_fuse($unavailable);
if ($is_milestone) {
foreach ($fields as $key => $field) {
$xaction_type = $field->getTransactionType();
if (isset($unavailable[$xaction_type])) {
unset($fields[$key]);
}
}
}
return $fields;
}
protected function newBuiltinEngineConfigurations() {
$configuration = head(parent::newBuiltinEngineConfigurations());
// TODO: This whole method is clumsy, and the ordering for the custom
// field is especially clumsy. Maybe try to make this more natural to
// express.
$configuration
->setFieldOrder(
array(
'parent',
'milestone',
'name',
'std:project:internal:description',
'icon',
'color',
'slugs',
));
return array(
$configuration,
);
}
protected function buildCustomEditFields($object) {
$slugs = mpull($object->getSlugs(), 'getSlug');
$slugs = array_fuse($slugs);
unset($slugs[$object->getPrimarySlug()]);
$slugs = array_values($slugs);
$milestone = $this->getMilestoneProject();
$parent = $this->getParentProject();
if ($parent) {
$parent_phid = $parent->getPHID();
} else {
$parent_phid = null;
}
if ($milestone) {
$milestone_phid = $milestone->getPHID();
} else {
$milestone_phid = null;
}
$fields = array(
id(new PhabricatorHandlesEditField())
->setKey('parent')
->setLabel(pht('Parent'))
->setDescription(pht('Create a subproject of an existing project.'))
->setConduitDescription(
pht('Choose a parent project to create a subproject beneath.'))
->setConduitTypeDescription(pht('PHID of the parent project.'))
->setAliases(array('parentPHID'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_PARENT)
->setHandleParameterType(new AphrontPHIDHTTPParameterType())
->setSingleValue($parent_phid)
->setIsReorderable(false)
->setIsDefaultable(false)
->setIsLockable(false)
->setIsLocked(true),
id(new PhabricatorHandlesEditField())
->setKey('milestone')
->setLabel(pht('Milestone Of'))
->setDescription(pht('Parent project to create a milestone for.'))
->setConduitDescription(
pht('Choose a parent project to create a new milestone for.'))
->setConduitTypeDescription(pht('PHID of the parent project.'))
->setAliases(array('milestonePHID'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_MILESTONE)
->setHandleParameterType(new AphrontPHIDHTTPParameterType())
->setSingleValue($milestone_phid)
->setIsReorderable(false)
->setIsDefaultable(false)
->setIsLockable(false)
->setIsLocked(true),
id(new PhabricatorTextEditField())
->setKey('name')
->setLabel(pht('Name'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_NAME)
->setIsRequired(true)
->setDescription(pht('Project name.'))
->setConduitDescription(pht('Rename the project'))
->setConduitTypeDescription(pht('New project name.'))
->setValue($object->getName()),
id(new PhabricatorIconSetEditField())
->setKey('icon')
->setLabel(pht('Icon'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_ICON)
->setIconSet(new PhabricatorProjectIconSet())
->setDescription(pht('Project icon.'))
->setConduitDescription(pht('Change the project icon.'))
->setConduitTypeDescription(pht('New project icon.'))
->setValue($object->getIcon()),
id(new PhabricatorSelectEditField())
->setKey('color')
->setLabel(pht('Color'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_COLOR)
->setOptions(PhabricatorProjectIconSet::getColorMap())
->setDescription(pht('Project tag color.'))
->setConduitDescription(pht('Change the project tag color.'))
->setConduitTypeDescription(pht('New project tag color.'))
->setValue($object->getColor()),
id(new PhabricatorStringListEditField())
->setKey('slugs')
->setLabel(pht('Additional Hashtags'))
->setTransactionType(PhabricatorProjectTransaction::TYPE_SLUGS)
->setDescription(pht('Additional project slugs.'))
->setConduitDescription(pht('Change project slugs.'))
->setConduitTypeDescription(pht('New list of slugs.'))
->setValue($slugs),
);
$can_edit_members = (!$milestone) &&
(!$object->isMilestone()) &&
(!$object->getHasSubprojects());
if ($can_edit_members) {
// Show this on the web UI when creating a project, but not when editing
// one. It is always available via Conduit.
$conduit_only = !$this->getIsCreate();
$members_field = id(new PhabricatorUsersEditField())
->setKey('members')
->setAliases(array('memberPHIDs'))
->setLabel(pht('Initial Members'))
->setIsConduitOnly($conduit_only)
->setUseEdgeTransactions(true)
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue(
'edge:type',
PhabricatorProjectProjectHasMemberEdgeType::EDGECONST)
->setDescription(pht('Initial project members.'))
->setConduitDescription(pht('Set project members.'))
->setConduitTypeDescription(pht('New list of members.'))
->setValue(array());
$members_field->setViewer($this->getViewer());
$edit_add = $members_field->getConduitEditType('members.add')
->setConduitDescription(pht('Add members.'));
$edit_set = $members_field->getConduitEditType('members.set')
->setConduitDescription(
pht('Set members, overwriting the current value.'));
$edit_rem = $members_field->getConduitEditType('members.remove')
->setConduitDescription(pht('Remove members.'));
$fields[] = $members_field;
}
return $fields;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Dec 24, 5:40 PM (1 d, 13 h)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6921705
Default Alt Text
(15 KB)

Event Timeline