Differential D14909 Diff 36034 src/applications/project/editor/PhabricatorProjectTransactionEditor.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/project/editor/PhabricatorProjectTransactionEditor.php
<?php | <?php | ||||
final class PhabricatorProjectTransactionEditor | final class PhabricatorProjectTransactionEditor | ||||
extends PhabricatorApplicationTransactionEditor { | extends PhabricatorApplicationTransactionEditor { | ||||
private $isMilestone; | |||||
private function setIsMilestone($is_milestone) { | |||||
$this->isMilestone = $is_milestone; | |||||
return $this; | |||||
} | |||||
private function getIsMilestone() { | |||||
return $this->isMilestone; | |||||
} | |||||
public function getEditorApplicationClass() { | public function getEditorApplicationClass() { | ||||
return 'PhabricatorProjectApplication'; | return 'PhabricatorProjectApplication'; | ||||
} | } | ||||
public function getEditorObjectsDescription() { | public function getEditorObjectsDescription() { | ||||
return pht('Projects'); | return pht('Projects'); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | final class PhabricatorProjectTransactionEditor | ||||
protected function applyCustomInternalTransaction( | protected function applyCustomInternalTransaction( | ||||
PhabricatorLiskDAO $object, | PhabricatorLiskDAO $object, | ||||
PhabricatorApplicationTransaction $xaction) { | PhabricatorApplicationTransaction $xaction) { | ||||
switch ($xaction->getTransactionType()) { | switch ($xaction->getTransactionType()) { | ||||
case PhabricatorProjectTransaction::TYPE_NAME: | case PhabricatorProjectTransaction::TYPE_NAME: | ||||
$name = $xaction->getNewValue(); | $name = $xaction->getNewValue(); | ||||
$object->setName($name); | $object->setName($name); | ||||
if ($this->getIsMilestone()) { | |||||
$object->setPrimarySlug(PhabricatorSlug::normalizeProjectSlug($name)); | $object->setPrimarySlug(PhabricatorSlug::normalizeProjectSlug($name)); | ||||
} | |||||
return; | return; | ||||
case PhabricatorProjectTransaction::TYPE_SLUGS: | case PhabricatorProjectTransaction::TYPE_SLUGS: | ||||
return; | return; | ||||
case PhabricatorProjectTransaction::TYPE_STATUS: | case PhabricatorProjectTransaction::TYPE_STATUS: | ||||
$object->setStatus($xaction->getNewValue()); | $object->setStatus($xaction->getNewValue()); | ||||
return; | return; | ||||
case PhabricatorProjectTransaction::TYPE_IMAGE: | case PhabricatorProjectTransaction::TYPE_IMAGE: | ||||
$object->setProfileImagePHID($xaction->getNewValue()); | $object->setProfileImagePHID($xaction->getNewValue()); | ||||
return; | return; | ||||
case PhabricatorProjectTransaction::TYPE_ICON: | case PhabricatorProjectTransaction::TYPE_ICON: | ||||
$object->setIcon($xaction->getNewValue()); | $object->setIcon($xaction->getNewValue()); | ||||
return; | return; | ||||
case PhabricatorProjectTransaction::TYPE_COLOR: | case PhabricatorProjectTransaction::TYPE_COLOR: | ||||
$object->setColor($xaction->getNewValue()); | $object->setColor($xaction->getNewValue()); | ||||
return; | return; | ||||
case PhabricatorProjectTransaction::TYPE_LOCKED: | case PhabricatorProjectTransaction::TYPE_LOCKED: | ||||
$object->setIsMembershipLocked($xaction->getNewValue()); | $object->setIsMembershipLocked($xaction->getNewValue()); | ||||
return; | return; | ||||
case PhabricatorProjectTransaction::TYPE_PARENT: | case PhabricatorProjectTransaction::TYPE_PARENT: | ||||
$object->setParentProjectPHID($xaction->getNewValue()); | $object->setParentProjectPHID($xaction->getNewValue()); | ||||
return; | return; | ||||
case PhabricatorProjectTransaction::TYPE_MILESTONE: | case PhabricatorProjectTransaction::TYPE_MILESTONE: | ||||
$current = queryfx_one( | $number = $object->getParentProject()->loadNextMilestoneNumber(); | ||||
$object->establishConnection('w'), | |||||
'SELECT MAX(milestoneNumber) n | |||||
FROM %T | |||||
WHERE parentProjectPHID = %s', | |||||
$object->getTableName(), | |||||
$object->getParentProject()->getPHID()); | |||||
if (!$current) { | |||||
$number = 1; | |||||
} else { | |||||
$number = (int)$current['n'] + 1; | |||||
} | |||||
$object->setMilestoneNumber($number); | $object->setMilestoneNumber($number); | ||||
$object->setParentProjectPHID($xaction->getNewValue()); | $object->setParentProjectPHID($xaction->getNewValue()); | ||||
return; | return; | ||||
} | } | ||||
return parent::applyCustomInternalTransaction($object, $xaction); | return parent::applyCustomInternalTransaction($object, $xaction); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | foreach ($xactions as $xaction) { | ||||
'project or milestone project. A project can not be both a '. | 'project or milestone project. A project can not be both a '. | ||||
'subproject and a milestone.'), | 'subproject and a milestone.'), | ||||
$xaction); | $xaction); | ||||
break; | break; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
$is_milestone = $object->isMilestone(); | $is_milestone = $this->getIsMilestone(); | ||||
foreach ($xactions as $xaction) { | |||||
switch ($xaction->getTransactionType()) { | |||||
case PhabricatorProjectTransaction::TYPE_MILESTONE: | |||||
if ($xaction->getNewValue() !== null) { | |||||
$is_milestone = true; | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
$is_parent = $object->getHasSubprojects(); | $is_parent = $object->getHasSubprojects(); | ||||
foreach ($xactions as $xaction) { | foreach ($xactions as $xaction) { | ||||
switch ($xaction->getTransactionType()) { | switch ($xaction->getTransactionType()) { | ||||
case PhabricatorProjectTransaction::TYPE_MEMBERS: | case PhabricatorProjectTransaction::TYPE_MEMBERS: | ||||
if ($is_parent) { | if ($is_parent) { | ||||
$errors[] = new PhabricatorApplicationTransactionValidationError( | $errors[] = new PhabricatorApplicationTransactionValidationError( | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | switch ($type) { | ||||
$error->setIsMissingFieldError(true); | $error->setIsMissingFieldError(true); | ||||
$errors[] = $error; | $errors[] = $error; | ||||
} | } | ||||
if (!$xactions) { | if (!$xactions) { | ||||
break; | break; | ||||
} | } | ||||
if ($this->getIsMilestone()) { | |||||
break; | |||||
} | |||||
$name = last($xactions)->getNewValue(); | $name = last($xactions)->getNewValue(); | ||||
if (!PhabricatorSlug::isValidProjectSlug($name)) { | if (!PhabricatorSlug::isValidProjectSlug($name)) { | ||||
$errors[] = new PhabricatorApplicationTransactionValidationError( | $errors[] = new PhabricatorApplicationTransactionValidationError( | ||||
$type, | $type, | ||||
pht('Invalid'), | pht('Invalid'), | ||||
pht( | pht( | ||||
'Project names must contain at least one letter or number.'), | 'Project names must contain at least one letter or number.'), | ||||
last($xactions)); | last($xactions)); | ||||
break; | break; | ||||
} | } | ||||
$name_used_already = id(new PhabricatorProjectQuery()) | |||||
->setViewer($this->getActor()) | |||||
->withNames(array($name)) | |||||
->executeOne(); | |||||
if ($name_used_already && | |||||
($name_used_already->getPHID() != $object->getPHID())) { | |||||
$error = new PhabricatorApplicationTransactionValidationError( | |||||
$type, | |||||
pht('Duplicate'), | |||||
pht('Project name is already used.'), | |||||
nonempty(last($xactions), null)); | |||||
$errors[] = $error; | |||||
} | |||||
$slug = PhabricatorSlug::normalizeProjectSlug($name); | $slug = PhabricatorSlug::normalizeProjectSlug($name); | ||||
$slug_used_already = id(new PhabricatorProjectSlug()) | $slug_used_already = id(new PhabricatorProjectSlug()) | ||||
->loadOneWhere('slug = %s', $slug); | ->loadOneWhere('slug = %s', $slug); | ||||
if ($slug_used_already && | if ($slug_used_already && | ||||
$slug_used_already->getProjectPHID() != $object->getPHID()) { | $slug_used_already->getProjectPHID() != $object->getPHID()) { | ||||
$error = new PhabricatorApplicationTransactionValidationError( | $error = new PhabricatorApplicationTransactionValidationError( | ||||
$type, | $type, | ||||
pht('Duplicate'), | pht('Duplicate'), | ||||
pht('Project name can not be used due to hashtag collision.'), | pht( | ||||
'Project name generates the same hashtag ("%s") as another '. | |||||
'existing project. Choose a unique name.', | |||||
'#'.$slug), | |||||
nonempty(last($xactions), null)); | nonempty(last($xactions), null)); | ||||
$errors[] = $error; | $errors[] = $error; | ||||
} | } | ||||
break; | break; | ||||
case PhabricatorProjectTransaction::TYPE_SLUGS: | case PhabricatorProjectTransaction::TYPE_SLUGS: | ||||
if (!$xactions) { | if (!$xactions) { | ||||
break; | break; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 485 Lines • ▼ Show 20 Lines | if ($this->getIsNewObject() && $is_web) { | ||||
->setMetadataValue('edge:type', $type_member) | ->setMetadataValue('edge:type', $type_member) | ||||
->setNewValue( | ->setNewValue( | ||||
array( | array( | ||||
'+' => array($actor_phid => $actor_phid), | '+' => array($actor_phid => $actor_phid), | ||||
)); | )); | ||||
} | } | ||||
} | } | ||||
$is_milestone = $object->isMilestone(); | |||||
foreach ($xactions as $xaction) { | |||||
switch ($xaction->getTransactionType()) { | |||||
case PhabricatorProjectTransaction::TYPE_MILESTONE: | |||||
if ($xaction->getNewValue() !== null) { | |||||
$is_milestone = true; | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
$this->setIsMilestone($is_milestone); | |||||
return $results; | return $results; | ||||
} | } | ||||
} | } |