diff --git a/src/applications/drydock/constants/DrydockLeaseStatus.php b/src/applications/drydock/constants/DrydockLeaseStatus.php index 39f4ce5e1b..f37e4ab9be 100644 --- a/src/applications/drydock/constants/DrydockLeaseStatus.php +++ b/src/applications/drydock/constants/DrydockLeaseStatus.php @@ -1,36 +1,32 @@ pht('Pending'), self::STATUS_ACQUIRED => pht('Acquired'), self::STATUS_ACTIVE => pht('Active'), self::STATUS_RELEASED => pht('Released'), self::STATUS_BROKEN => pht('Broken'), self::STATUS_DESTROYED => pht('Destroyed'), ); + } + public static function getNameForStatus($status) { + $map = self::getStatusMap(); return idx($map, $status, pht('Unknown')); } public static function getAllStatuses() { - return array( - self::STATUS_PENDING, - self::STATUS_ACQUIRED, - self::STATUS_ACTIVE, - self::STATUS_RELEASED, - self::STATUS_BROKEN, - self::STATUS_DESTROYED, - ); + return array_keys(self::getStatusMap()); } } diff --git a/src/applications/drydock/constants/DrydockResourceStatus.php b/src/applications/drydock/constants/DrydockResourceStatus.php index d88f77625a..d8a860d6a0 100644 --- a/src/applications/drydock/constants/DrydockResourceStatus.php +++ b/src/applications/drydock/constants/DrydockResourceStatus.php @@ -1,33 +1,30 @@ pht('Pending'), self::STATUS_ACTIVE => pht('Active'), self::STATUS_RELEASED => pht('Released'), self::STATUS_BROKEN => pht('Broken'), self::STATUS_DESTROYED => pht('Destroyed'), ); + } + public static function getNameForStatus($status) { + $map = self::getStatusMap(); return idx($map, $status, pht('Unknown')); } public static function getAllStatuses() { - return array( - self::STATUS_PENDING, - self::STATUS_ACTIVE, - self::STATUS_RELEASED, - self::STATUS_BROKEN, - self::STATUS_DESTROYED, - ); + return array_keys(self::getStatusMap()); } } diff --git a/src/applications/drydock/customfield/DrydockBlueprintCoreCustomField.php b/src/applications/drydock/customfield/DrydockBlueprintCoreCustomField.php index 4317242c10..f4e6ba3a27 100644 --- a/src/applications/drydock/customfield/DrydockBlueprintCoreCustomField.php +++ b/src/applications/drydock/customfield/DrydockBlueprintCoreCustomField.php @@ -1,47 +1,53 @@ hasImplementation()) { + return array(); + } + $impl = $object->getImplementation(); $specs = $impl->getFieldSpecifications(); return PhabricatorStandardCustomField::buildStandardFields($this, $specs); } public function shouldUseStorage() { return false; } public function readValueFromObject(PhabricatorCustomFieldInterface $object) { $key = $this->getProxy()->getRawStandardFieldKey(); $this->setValueFromStorage($object->getDetail($key)); } public function applyApplicationTransactionInternalEffects( PhabricatorApplicationTransaction $xaction) { $object = $this->getObject(); $key = $this->getProxy()->getRawStandardFieldKey(); $this->setValueFromApplicationTransactions($xaction->getNewValue()); $value = $this->getValueForStorage(); $object->setDetail($key, $value); } public function applyApplicationTransactionExternalEffects( PhabricatorApplicationTransaction $xaction) { return; } public function getBlueprintFieldValue() { return $this->getProxy()->getFieldValue(); } } diff --git a/src/applications/drydock/query/DrydockBlueprintQuery.php b/src/applications/drydock/query/DrydockBlueprintQuery.php index c8e53217c9..7404c9457a 100644 --- a/src/applications/drydock/query/DrydockBlueprintQuery.php +++ b/src/applications/drydock/query/DrydockBlueprintQuery.php @@ -1,105 +1,88 @@ ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withBlueprintClasses(array $classes) { $this->blueprintClasses = $classes; return $this; } public function withDatasourceQuery($query) { $this->datasourceQuery = $query; return $this; } public function newResultObject() { return new DrydockBlueprint(); } protected function loadPage() { return $this->loadStandardPage($this->newResultObject()); } protected function willFilterPage(array $blueprints) { $impls = DrydockBlueprintImplementation::getAllBlueprintImplementations(); foreach ($blueprints as $key => $blueprint) { $impl = idx($impls, $blueprint->getClassName()); if (!$impl) { $this->didRejectResult($blueprint); unset($blueprints[$key]); continue; } $impl = clone $impl; $blueprint->attachImplementation($impl); } return $blueprints; } protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); if ($this->ids !== null) { $where[] = qsprintf( $conn, 'id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf( $conn, 'phid IN (%Ls)', $this->phids); } if ($this->datasourceQuery !== null) { $where[] = qsprintf( $conn, 'blueprintName LIKE %>', $this->datasourceQuery); } if ($this->blueprintClasses !== null) { $where[] = qsprintf( $conn, 'className IN (%Ls)', $this->blueprintClasses); } return $where; } - public function getOrderableColumns() { - // TODO: Blueprints implement CustomFields, but can not be ordered by - // custom field classes because the custom fields are not global. There - // is no graceful way to handle this in ApplicationSearch at the moment. - // Just brute force around it until we can clean this up. - - return array( - 'id' => array( - 'table' => $this->getPrimaryTableAlias(), - 'column' => 'id', - 'reverse' => false, - 'type' => 'int', - 'unique' => true, - ), - ); - } - } diff --git a/src/applications/drydock/query/DrydockBlueprintSearchEngine.php b/src/applications/drydock/query/DrydockBlueprintSearchEngine.php index ccb4c80803..a0420c610c 100644 --- a/src/applications/drydock/query/DrydockBlueprintSearchEngine.php +++ b/src/applications/drydock/query/DrydockBlueprintSearchEngine.php @@ -1,79 +1,81 @@ newQuery(); + + return $query; } - public function buildSearchForm( - AphrontFormView $form, - PhabricatorSavedQuery $saved) {} + protected function buildCustomSearchFields() { + return array(); + } protected function getURI($path) { return '/drydock/blueprint/'.$path; } protected function getBuiltinQueryNames() { return array( 'all' => pht('All Blueprints'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $blueprints, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($blueprints, 'DrydockBlueprint'); $viewer = $this->requireViewer(); $view = new PHUIObjectItemListView(); foreach ($blueprints as $blueprint) { $item = id(new PHUIObjectItemView()) ->setHeader($blueprint->getBlueprintName()) ->setHref($this->getApplicationURI('/blueprint/'.$blueprint->getID())) ->setObjectName(pht('Blueprint %d', $blueprint->getID())); if (!$blueprint->getImplementation()->isEnabled()) { $item->setDisabled(true); } $item->addAttribute($blueprint->getImplementation()->getBlueprintName()); $view->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($view); $result->setNoDataString(pht('No blueprints found.')); return $result; } } diff --git a/src/applications/drydock/query/DrydockLeaseSearchEngine.php b/src/applications/drydock/query/DrydockLeaseSearchEngine.php index eb5338b2cb..7d85ddbe70 100644 --- a/src/applications/drydock/query/DrydockLeaseSearchEngine.php +++ b/src/applications/drydock/query/DrydockLeaseSearchEngine.php @@ -1,100 +1,81 @@ setParameter( - 'statuses', - $this->readListFromRequest($request, 'statuses')); - - return $saved; + public function newQuery() { + return new DrydockLeaseQuery(); } - public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { - $query = id(new DrydockLeaseQuery()); + protected function buildQueryFromParameters(array $map) { + $query = $this->newQuery(); - $statuses = $saved->getParameter('statuses', array()); - if ($statuses) { - $query->withStatuses($statuses); + if ($map['statuses']) { + $query->withStatuses($map['statuses']); } return $query; } - public function buildSearchForm( - AphrontFormView $form, - PhabricatorSavedQuery $saved) { - - $statuses = $saved->getParameter('statuses', array()); - - $status_control = id(new AphrontFormCheckboxControl()) - ->setLabel(pht('Status')); - foreach (DrydockLeaseStatus::getAllStatuses() as $status) { - $status_control->addCheckbox( - 'statuses[]', - $status, - DrydockLeaseStatus::getNameForStatus($status), - in_array($status, $statuses)); - } - - $form - ->appendChild($status_control); - + protected function buildCustomSearchFields() { + return array( + id(new PhabricatorSearchCheckboxesField()) + ->setLabel(pht('Statuses')) + ->setKey('statuses') + ->setOptions(DrydockLeaseStatus::getStatusMap()), + ); } protected function getURI($path) { return '/drydock/lease/'.$path; } protected function getBuiltinQueryNames() { return array( 'active' => pht('Active Leases'), 'all' => pht('All Leases'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'active': return $query->setParameter( 'statuses', array( DrydockLeaseStatus::STATUS_PENDING, DrydockLeaseStatus::STATUS_ACQUIRED, DrydockLeaseStatus::STATUS_ACTIVE, )); case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $leases, PhabricatorSavedQuery $saved, array $handles) { $list = id(new DrydockLeaseListView()) ->setUser($this->requireViewer()) ->setLeases($leases); return id(new PhabricatorApplicationSearchResultView()) ->setContent($list); } } diff --git a/src/applications/drydock/query/DrydockResourceSearchEngine.php b/src/applications/drydock/query/DrydockResourceSearchEngine.php index 2ebd3971d0..7b0bca0324 100644 --- a/src/applications/drydock/query/DrydockResourceSearchEngine.php +++ b/src/applications/drydock/query/DrydockResourceSearchEngine.php @@ -1,100 +1,82 @@ setParameter( - 'statuses', - $this->readListFromRequest($request, 'statuses')); - - return $saved; + public function newQuery() { + return new DrydockResourceQuery(); } - public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { - $query = id(new DrydockResourceQuery()); + protected function buildQueryFromParameters(array $map) { + $query = $this->newQuery(); - $statuses = $saved->getParameter('statuses', array()); - if ($statuses) { - $query->withStatuses($statuses); + if ($map['statuses']) { + $query->withStatuses($map['statuses']); } return $query; } - public function buildSearchForm( - AphrontFormView $form, - PhabricatorSavedQuery $saved) { - - $statuses = $saved->getParameter('statuses', array()); - - $status_control = id(new AphrontFormCheckboxControl()) - ->setLabel(pht('Status')); - foreach (DrydockResourceStatus::getAllStatuses() as $status) { - $status_control->addCheckbox( - 'statuses[]', - $status, - DrydockResourceStatus::getNameForStatus($status), - in_array($status, $statuses)); - } - - $form - ->appendChild($status_control); + protected function buildCustomSearchFields() { + return array( + id(new PhabricatorSearchCheckboxesField()) + ->setLabel(pht('Statuses')) + ->setKey('statuses') + ->setOptions(DrydockResourceStatus::getStatusMap()), + ); } protected function getURI($path) { return '/drydock/resource/'.$path; } protected function getBuiltinQueryNames() { return array( 'active' => pht('Active Resources'), 'all' => pht('All Resources'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'active': return $query->setParameter( 'statuses', array( DrydockResourceStatus::STATUS_PENDING, DrydockResourceStatus::STATUS_ACTIVE, )); case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $resources, PhabricatorSavedQuery $query, array $handles) { $list = id(new DrydockResourceListView()) ->setUser($this->requireViewer()) ->setResources($resources); $result = new PhabricatorApplicationSearchResultView(); $result->setTable($list); return $result; } } diff --git a/src/applications/drydock/storage/DrydockBlueprint.php b/src/applications/drydock/storage/DrydockBlueprint.php index ed83ded571..c687c996a9 100644 --- a/src/applications/drydock/storage/DrydockBlueprint.php +++ b/src/applications/drydock/storage/DrydockBlueprint.php @@ -1,318 +1,322 @@ setViewer($actor) ->withClasses(array('PhabricatorDrydockApplication')) ->executeOne(); $view_policy = $app->getPolicy( DrydockDefaultViewCapability::CAPABILITY); $edit_policy = $app->getPolicy( DrydockDefaultEditCapability::CAPABILITY); return id(new DrydockBlueprint()) ->setViewPolicy($view_policy) ->setEditPolicy($edit_policy) ->setBlueprintName(''); } protected function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, self::CONFIG_SERIALIZATION => array( 'details' => self::SERIALIZATION_JSON, ), self::CONFIG_COLUMN_SCHEMA => array( 'className' => 'text255', 'blueprintName' => 'sort255', ), ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID( DrydockBlueprintPHIDType::TYPECONST); } public function getImplementation() { return $this->assertAttached($this->implementation); } public function attachImplementation(DrydockBlueprintImplementation $impl) { $this->implementation = $impl; return $this; } + public function hasImplementation() { + return ($this->implementation !== self::ATTACHABLE); + } + public function getDetail($key, $default = null) { return idx($this->details, $key, $default); } public function setDetail($key, $value) { $this->details[$key] = $value; return $this; } public function getFieldValue($key) { $key = "std:drydock:core:{$key}"; $fields = $this->loadCustomFields(); $field = idx($fields, $key); if (!$field) { throw new Exception( pht( 'Unknown blueprint field "%s"!', $key)); } return $field->getBlueprintFieldValue(); } private function loadCustomFields() { if ($this->fields === null) { $field_list = PhabricatorCustomField::getObjectFields( $this, PhabricatorCustomField::ROLE_VIEW); $field_list->readFieldsFromStorage($this); $this->fields = $field_list->getFields(); } return $this->fields; } /* -( Allocating Resources )----------------------------------------------- */ /** * @task resource */ public function canEverAllocateResourceForLease(DrydockLease $lease) { return $this->getImplementation()->canEverAllocateResourceForLease( $this, $lease); } /** * @task resource */ public function canAllocateResourceForLease(DrydockLease $lease) { return $this->getImplementation()->canAllocateResourceForLease( $this, $lease); } /** * @task resource */ public function allocateResource(DrydockLease $lease) { return $this->getImplementation()->allocateResource( $this, $lease); } /** * @task resource */ public function activateResource(DrydockResource $resource) { return $this->getImplementation()->activateResource( $this, $resource); } /** * @task resource */ public function destroyResource(DrydockResource $resource) { $this->getImplementation()->destroyResource( $this, $resource); return $this; } /* -( Acquiring Leases )--------------------------------------------------- */ /** * @task lease */ public function canAcquireLeaseOnResource( DrydockResource $resource, DrydockLease $lease) { return $this->getImplementation()->canAcquireLeaseOnResource( $this, $resource, $lease); } /** * @task lease */ public function acquireLease( DrydockResource $resource, DrydockLease $lease) { return $this->getImplementation()->acquireLease( $this, $resource, $lease); } /** * @task lease */ public function activateLease( DrydockResource $resource, DrydockLease $lease) { return $this->getImplementation()->activateLease( $this, $resource, $lease); } /** * @task lease */ public function didReleaseLease( DrydockResource $resource, DrydockLease $lease) { $this->getImplementation()->didReleaseLease( $this, $resource, $lease); return $this; } /** * @task lease */ public function destroyLease( DrydockResource $resource, DrydockLease $lease) { $this->getImplementation()->destroyLease( $this, $resource, $lease); return $this; } public function getInterface( DrydockResource $resource, DrydockLease $lease, $type) { $interface = $this->getImplementation() ->getInterface($this, $resource, $lease, $type); if (!$interface) { throw new Exception( pht( 'Unable to build resource interface of type "%s".', $type)); } return $interface; } /* -( PhabricatorApplicationTransactionInterface )------------------------- */ public function getApplicationTransactionEditor() { return new DrydockBlueprintEditor(); } public function getApplicationTransactionObject() { return $this; } public function getApplicationTransactionTemplate() { return new DrydockBlueprintTransaction(); } public function willRenderTimeline( PhabricatorApplicationTransactionView $timeline, AphrontRequest $request) { return $timeline; } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, ); } public function getPolicy($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: return $this->getViewPolicy(); case PhabricatorPolicyCapability::CAN_EDIT: return $this->getEditPolicy(); } } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { return false; } public function describeAutomaticCapability($capability) { return null; } /* -( PhabricatorCustomFieldInterface )------------------------------------ */ public function getCustomFieldSpecificationForRole($role) { return array(); } public function getCustomFieldBaseClass() { return 'DrydockBlueprintCustomField'; } public function getCustomFields() { return $this->assertAttached($this->customFields); } public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) { $this->customFields = $fields; return $this; } }