mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-30 02:32:42 +01:00
Validate menu item fields (links, projects, dashboards, applications, forms, etc)
Summary: Ref T12128. This adds validation to menu items. This feels a touch flimsy-ish (kind of copy/paste heavy?) but maybe it can be cleaned up a bit once some similar lightweight modular item types (build steps in Harbormaster, blueprints in Drydock) convert. Test Plan: - Tried to create each item with errors (no dashboard, no project, etc). Got appropriate form errors. - Created valid items of each type. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12128 Differential Revision: https://secure.phabricator.com/D17235
This commit is contained in:
parent
98a29f3de9
commit
8113b76910
10 changed files with 396 additions and 7 deletions
|
@ -149,4 +149,47 @@ final class PhabricatorProfileMenuEditEngine
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getValidationExceptionShortMessage(
|
||||||
|
PhabricatorApplicationTransactionValidationException $ex,
|
||||||
|
PhabricatorEditField $field) {
|
||||||
|
|
||||||
|
// Menu item properties all have the same transaction type, so we need
|
||||||
|
// to make sure errors about a specific property (like the URI for a
|
||||||
|
// link) are only applied to the field for that particular property. If
|
||||||
|
// we don't do this, the red error text like "Required" will display
|
||||||
|
// next to every field.
|
||||||
|
|
||||||
|
$property_type =
|
||||||
|
PhabricatorProfileMenuItemConfigurationTransaction::TYPE_PROPERTY;
|
||||||
|
|
||||||
|
$xaction_type = $field->getTransactionType();
|
||||||
|
if ($xaction_type == $property_type) {
|
||||||
|
$field_key = $field->getKey();
|
||||||
|
foreach ($ex->getErrors() as $error) {
|
||||||
|
if ($error->getType() !== $xaction_type) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$xaction = $error->getTransaction();
|
||||||
|
if (!$xaction) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$xaction_setting = $xaction->getMetadataValue('property.key');
|
||||||
|
if ($xaction_setting != $field_key) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$short_message = $error->getShortMessage();
|
||||||
|
if ($short_message !== null) {
|
||||||
|
return $short_message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getValidationExceptionShortMessage($ex, $field);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,4 +87,39 @@ final class PhabricatorProfileMenuEditor
|
||||||
return parent::applyCustomExternalTransaction($object, $xaction);
|
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function validateTransaction(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
$type,
|
||||||
|
array $xactions) {
|
||||||
|
|
||||||
|
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||||
|
|
||||||
|
$actor = $this->getActor();
|
||||||
|
$menu_item = $object->getMenuItem();
|
||||||
|
$menu_item->setViewer($actor);
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case PhabricatorProfileMenuItemConfigurationTransaction::TYPE_PROPERTY:
|
||||||
|
$key_map = array();
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$xaction_key = $xaction->getMetadataValue('property.key');
|
||||||
|
$old = $this->getCustomTransactionOldValue($object, $xaction);
|
||||||
|
$new = $xaction->getNewValue();
|
||||||
|
$key_map[$xaction_key][] = array(
|
||||||
|
'xaction' => $xaction,
|
||||||
|
'old' => $old,
|
||||||
|
'new' => $new,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($object->validateTransactions($key_map) as $error) {
|
||||||
|
$errors[] = $error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ final class PhabricatorApplicationProfileMenuItem
|
||||||
|
|
||||||
const MENUITEMKEY = 'application';
|
const MENUITEMKEY = 'application';
|
||||||
|
|
||||||
|
const FIELD_APPLICATION = 'application';
|
||||||
|
|
||||||
public function getMenuItemTypeIcon() {
|
public function getMenuItemTypeIcon() {
|
||||||
return 'fa-globe';
|
return 'fa-globe';
|
||||||
}
|
}
|
||||||
|
@ -32,10 +34,11 @@ final class PhabricatorApplicationProfileMenuItem
|
||||||
PhabricatorProfileMenuItemConfiguration $config) {
|
PhabricatorProfileMenuItemConfiguration $config) {
|
||||||
return array(
|
return array(
|
||||||
id(new PhabricatorDatasourceEditField())
|
id(new PhabricatorDatasourceEditField())
|
||||||
->setKey('application')
|
->setKey(self::FIELD_APPLICATION)
|
||||||
->setLabel(pht('Application'))
|
->setLabel(pht('Application'))
|
||||||
->setIsRequired(true)
|
->setIsRequired(true)
|
||||||
->setDatasource(new PhabricatorApplicationDatasource())
|
->setDatasource(new PhabricatorApplicationDatasource())
|
||||||
|
->setIsRequired(true)
|
||||||
->setSingleValue($config->getMenuItemProperty('application')),
|
->setSingleValue($config->getMenuItemProperty('application')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +47,7 @@ final class PhabricatorApplicationProfileMenuItem
|
||||||
PhabricatorProfileMenuItemConfiguration $config) {
|
PhabricatorProfileMenuItemConfiguration $config) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
$phid = $config->getMenuItemProperty('application');
|
$phid = $config->getMenuItemProperty('application');
|
||||||
|
|
||||||
$app = id(new PhabricatorApplicationQuery())
|
$app = id(new PhabricatorApplicationQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withPHIDs(array($phid))
|
->withPHIDs(array($phid))
|
||||||
|
@ -77,4 +81,49 @@ final class PhabricatorApplicationProfileMenuItem
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ final class PhabricatorDashboardProfileMenuItem
|
||||||
|
|
||||||
const MENUITEMKEY = 'dashboard';
|
const MENUITEMKEY = 'dashboard';
|
||||||
|
|
||||||
|
const FIELD_DASHBOARD = 'dashboardPHID';
|
||||||
|
|
||||||
private $dashboard;
|
private $dashboard;
|
||||||
|
|
||||||
public function getMenuItemTypeIcon() {
|
public function getMenuItemTypeIcon() {
|
||||||
|
@ -75,7 +77,7 @@ final class PhabricatorDashboardProfileMenuItem
|
||||||
->setLabel(pht('Name'))
|
->setLabel(pht('Name'))
|
||||||
->setValue($this->getName($config)),
|
->setValue($this->getName($config)),
|
||||||
id(new PhabricatorDatasourceEditField())
|
id(new PhabricatorDatasourceEditField())
|
||||||
->setKey('dashboardPHID')
|
->setKey(self::FIELD_DASHBOARD)
|
||||||
->setLabel(pht('Dashboard'))
|
->setLabel(pht('Dashboard'))
|
||||||
->setIsRequired(true)
|
->setIsRequired(true)
|
||||||
->setDatasource(new PhabricatorDashboardDatasource())
|
->setDatasource(new PhabricatorDashboardDatasource())
|
||||||
|
@ -110,4 +112,49 @@ final class PhabricatorDashboardProfileMenuItem
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function validateTransactions(
|
||||||
|
PhabricatorProfileMenuItemConfiguration $config,
|
||||||
|
$field_key,
|
||||||
|
$value,
|
||||||
|
array $xactions) {
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
if ($field_key == self::FIELD_DASHBOARD) {
|
||||||
|
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||||
|
$errors[] = $this->newRequiredError(
|
||||||
|
pht('You must choose a dashboard.'),
|
||||||
|
$field_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$new = $xaction['new'];
|
||||||
|
|
||||||
|
if (!$new) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($new === $value) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dashboards = id(new PhabricatorDashboardQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($new))
|
||||||
|
->execute();
|
||||||
|
if (!$dashboards) {
|
||||||
|
$errors[] = $this->newInvalidError(
|
||||||
|
pht(
|
||||||
|
'Dashboard "%s" is not a valid dashboard which you have '.
|
||||||
|
'permission to see.',
|
||||||
|
$new),
|
||||||
|
$xaction['xaction']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ final class PhabricatorEditEngineProfileMenuItem
|
||||||
|
|
||||||
const MENUITEMKEY = 'editengine';
|
const MENUITEMKEY = 'editengine';
|
||||||
|
|
||||||
|
const FIELD_FORM = 'formKey';
|
||||||
|
|
||||||
private $form;
|
private $form;
|
||||||
|
|
||||||
public function getMenuItemTypeIcon() {
|
public function getMenuItemTypeIcon() {
|
||||||
|
@ -51,7 +53,8 @@ final class PhabricatorEditEngineProfileMenuItem
|
||||||
|
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
$key = $item->getMenuItemProperty('formKey');
|
$key = $item->getMenuItemProperty('formKey');
|
||||||
list($engine_key, $form_key) = explode('/', $key);
|
list($engine_key, $form_key) = PhabricatorEditEngine::splitFullKey($key);
|
||||||
|
|
||||||
if (is_numeric($form_key)) {
|
if (is_numeric($form_key)) {
|
||||||
$form = idx($form_ids, $form_key, null);
|
$form = idx($form_ids, $form_key, null);
|
||||||
$item->getMenuItem()->attachForm($form);
|
$item->getMenuItem()->attachForm($form);
|
||||||
|
@ -83,7 +86,7 @@ final class PhabricatorEditEngineProfileMenuItem
|
||||||
->setLabel(pht('Name'))
|
->setLabel(pht('Name'))
|
||||||
->setValue($this->getName($config)),
|
->setValue($this->getName($config)),
|
||||||
id(new PhabricatorDatasourceEditField())
|
id(new PhabricatorDatasourceEditField())
|
||||||
->setKey('formKey')
|
->setKey(self::FIELD_FORM)
|
||||||
->setLabel(pht('Form'))
|
->setLabel(pht('Form'))
|
||||||
->setIsRequired(true)
|
->setIsRequired(true)
|
||||||
->setDatasource(new PhabricatorEditEngineDatasource())
|
->setDatasource(new PhabricatorEditEngineDatasource())
|
||||||
|
@ -120,4 +123,53 @@ final class PhabricatorEditEngineProfileMenuItem
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function validateTransactions(
|
||||||
|
PhabricatorProfileMenuItemConfiguration $config,
|
||||||
|
$field_key,
|
||||||
|
$value,
|
||||||
|
array $xactions) {
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
if ($field_key == self::FIELD_FORM) {
|
||||||
|
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||||
|
$errors[] = $this->newRequiredError(
|
||||||
|
pht('You must choose a form.'),
|
||||||
|
$field_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$new = $xaction['new'];
|
||||||
|
|
||||||
|
if (!$new) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($new === $value) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
list($engine_key, $form_key) = PhabricatorEditEngine::splitFullKey(
|
||||||
|
$new);
|
||||||
|
|
||||||
|
$forms = id(new PhabricatorEditEngineConfigurationQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withEngineKeys(array($engine_key))
|
||||||
|
->withIdentifiers(array($form_key))
|
||||||
|
->execute();
|
||||||
|
if (!$forms) {
|
||||||
|
$errors[] = $this->newInvalidError(
|
||||||
|
pht(
|
||||||
|
'Form "%s" is not a valid form which you have permission to '.
|
||||||
|
'see.',
|
||||||
|
$new),
|
||||||
|
$xaction['xaction']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@ final class PhabricatorLinkProfileMenuItem
|
||||||
|
|
||||||
const MENUITEMKEY = 'link';
|
const MENUITEMKEY = 'link';
|
||||||
|
|
||||||
|
const FIELD_URI = 'uri';
|
||||||
|
const FIELD_NAME = 'name';
|
||||||
|
|
||||||
public function getMenuItemTypeIcon() {
|
public function getMenuItemTypeIcon() {
|
||||||
return 'fa-link';
|
return 'fa-link';
|
||||||
}
|
}
|
||||||
|
@ -26,12 +29,12 @@ final class PhabricatorLinkProfileMenuItem
|
||||||
PhabricatorProfileMenuItemConfiguration $config) {
|
PhabricatorProfileMenuItemConfiguration $config) {
|
||||||
return array(
|
return array(
|
||||||
id(new PhabricatorTextEditField())
|
id(new PhabricatorTextEditField())
|
||||||
->setKey('name')
|
->setKey(self::FIELD_NAME)
|
||||||
->setLabel(pht('Name'))
|
->setLabel(pht('Name'))
|
||||||
->setIsRequired(true)
|
->setIsRequired(true)
|
||||||
->setValue($this->getLinkName($config)),
|
->setValue($this->getLinkName($config)),
|
||||||
id(new PhabricatorTextEditField())
|
id(new PhabricatorTextEditField())
|
||||||
->setKey('uri')
|
->setKey(self::FIELD_URI)
|
||||||
->setLabel(pht('URI'))
|
->setLabel(pht('URI'))
|
||||||
->setIsRequired(true)
|
->setIsRequired(true)
|
||||||
->setValue($this->getLinkURI($config)),
|
->setValue($this->getLinkURI($config)),
|
||||||
|
@ -91,4 +94,53 @@ final class PhabricatorLinkProfileMenuItem
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function validateTransactions(
|
||||||
|
PhabricatorProfileMenuItemConfiguration $config,
|
||||||
|
$field_key,
|
||||||
|
$value,
|
||||||
|
array $xactions) {
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
if ($field_key == self::FIELD_NAME) {
|
||||||
|
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||||
|
$errors[] = $this->newRequiredError(
|
||||||
|
pht('You must choose a link name.'),
|
||||||
|
$field_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($field_key == self::FIELD_URI) {
|
||||||
|
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||||
|
$errors[] = $this->newRequiredError(
|
||||||
|
pht('You must choose a URI to link to.'),
|
||||||
|
$field_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$new = $xaction['new'];
|
||||||
|
|
||||||
|
if (!$new) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($new === $value) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->isValidLinkURI($new)) {
|
||||||
|
$errors[] = $this->newInvalidError(
|
||||||
|
pht(
|
||||||
|
'URI "%s" is not a valid link URI. It should be a full, valid '.
|
||||||
|
'URI beginning with a protocol like "%s".',
|
||||||
|
$new,
|
||||||
|
'https://'),
|
||||||
|
$xaction['xaction']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,4 +70,41 @@ abstract class PhabricatorProfileMenuItem extends Phobject {
|
||||||
return new PHUIListItemView();
|
return new PHUIListItemView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function valdateTransactions(
|
||||||
|
PhabricatorProfileMenuItemConfiguration $config,
|
||||||
|
$field_key,
|
||||||
|
$value,
|
||||||
|
array $xactions) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected function isEmptyTransaction($value, array $xactions) {
|
||||||
|
$result = $value;
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$result = $xaction['new'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return !strlen($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected function newError($title, $message, $xaction = null) {
|
||||||
|
return new PhabricatorApplicationTransactionValidationError(
|
||||||
|
PhabricatorProfileMenuItemConfigurationTransaction::TYPE_PROPERTY,
|
||||||
|
$title,
|
||||||
|
$message,
|
||||||
|
$xaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected function newRequiredError($message, $type) {
|
||||||
|
$xaction = id(new PhabricatorProfileMenuItemConfigurationTransaction())
|
||||||
|
->setMetadataValue('property.key', $type);
|
||||||
|
|
||||||
|
return $this->newError(pht('Required'), $message, $xaction)
|
||||||
|
->setIsMissingFieldError(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected function newInvalidError($message, $xaction = null) {
|
||||||
|
return $this->newError(pht('Invalid'), $message, $xaction);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ final class PhabricatorProjectProfileMenuItem
|
||||||
extends PhabricatorProfileMenuItem {
|
extends PhabricatorProfileMenuItem {
|
||||||
|
|
||||||
const MENUITEMKEY = 'project';
|
const MENUITEMKEY = 'project';
|
||||||
|
const FIELD_PROJECT = 'project';
|
||||||
|
|
||||||
private $project;
|
private $project;
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ final class PhabricatorProjectProfileMenuItem
|
||||||
->setLabel(pht('Name'))
|
->setLabel(pht('Name'))
|
||||||
->setValue($this->getName($config)),
|
->setValue($this->getName($config)),
|
||||||
id(new PhabricatorDatasourceEditField())
|
id(new PhabricatorDatasourceEditField())
|
||||||
->setKey('project')
|
->setKey(self::FIELD_PROJECT)
|
||||||
->setLabel(pht('Project'))
|
->setLabel(pht('Project'))
|
||||||
->setIsRequired(true)
|
->setIsRequired(true)
|
||||||
->setDatasource(new PhabricatorProjectDatasource())
|
->setDatasource(new PhabricatorProjectDatasource())
|
||||||
|
@ -111,4 +112,49 @@ final class PhabricatorProjectProfileMenuItem
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function validateTransactions(
|
||||||
|
PhabricatorProfileMenuItemConfiguration $config,
|
||||||
|
$field_key,
|
||||||
|
$value,
|
||||||
|
array $xactions) {
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
if ($field_key == self::FIELD_PROJECT) {
|
||||||
|
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||||
|
$errors[] = $this->newRequiredError(
|
||||||
|
pht('You must choose a project.'),
|
||||||
|
$field_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$new = $xaction['new'];
|
||||||
|
|
||||||
|
if (!$new) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($new === $value) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$projects = id(new PhabricatorProjectQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($new))
|
||||||
|
->execute();
|
||||||
|
if (!$projects) {
|
||||||
|
$errors[] = $this->newInvalidError(
|
||||||
|
pht(
|
||||||
|
'Project "%s" is not a valid project which you have '.
|
||||||
|
'permission to see.',
|
||||||
|
$new),
|
||||||
|
$xaction['xaction']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,30 @@ final class PhabricatorProfileMenuItemConfiguration
|
||||||
return $this->getMenuItem()->willBuildNavigationItems($items);
|
return $this->getMenuItem()->willBuildNavigationItems($items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function validateTransactions(array $map) {
|
||||||
|
$item = $this->getMenuItem();
|
||||||
|
|
||||||
|
$fields = $item->buildEditEngineFields($this);
|
||||||
|
$errors = array();
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$field_key = $field->getKey();
|
||||||
|
|
||||||
|
$xactions = idx($map, $field_key, array());
|
||||||
|
$value = $this->getMenuItemProperty($field_key);
|
||||||
|
|
||||||
|
$field_errors = $item->validateTransactions(
|
||||||
|
$this,
|
||||||
|
$field_key,
|
||||||
|
$value,
|
||||||
|
$xactions);
|
||||||
|
foreach ($field_errors as $error) {
|
||||||
|
$errors[] = $error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSortVector() {
|
public function getSortVector() {
|
||||||
// Sort custom items above global items.
|
// Sort custom items above global items.
|
||||||
if ($this->getCustomPHID()) {
|
if ($this->getCustomPHID()) {
|
||||||
|
|
|
@ -95,6 +95,10 @@ abstract class PhabricatorEditEngine
|
||||||
return $keys;
|
return $keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function splitFullKey($full_key) {
|
||||||
|
return explode('/', $full_key, 2);
|
||||||
|
}
|
||||||
|
|
||||||
public function getQuickCreateOrderVector() {
|
public function getQuickCreateOrderVector() {
|
||||||
return id(new PhutilSortVector())
|
return id(new PhutilSortVector())
|
||||||
->addString($this->getObjectCreateShortText());
|
->addString($this->getObjectCreateShortText());
|
||||||
|
|
Loading…
Reference in a new issue