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; | ||||
| } | } | ||||
| } | } | ||||