diff --git a/src/applications/badges/conduit/PhabricatorBadgesEditConduitAPIMethod.php b/src/applications/badges/conduit/PhabricatorBadgesEditConduitAPIMethod.php index 42be0c2ba3..2ad0c92d32 100644 --- a/src/applications/badges/conduit/PhabricatorBadgesEditConduitAPIMethod.php +++ b/src/applications/badges/conduit/PhabricatorBadgesEditConduitAPIMethod.php @@ -1,19 +1,19 @@ loadRandomUser(); $recipient = $this->loadRandomUser(); $badge_phid = $this->loadRandomPHID(new PhabricatorBadgesBadge()); $xactions = array(); $xactions[] = array( 'type' => 'award', 'value' => array($recipient->getPHID()), ); $params = array( 'transactions' => $xactions, 'objectIdentifier' => $badge_phid, ); - $result = id(new ConduitCall('badges.edit', $params)) + $result = id(new ConduitCall('badge.edit', $params)) ->setUser($author) ->execute(); return $result['object']['phid']; } } diff --git a/src/applications/badges/lipsum/PhabricatorBadgesBadgeTestDataGenerator.php b/src/applications/badges/lipsum/PhabricatorBadgesBadgeTestDataGenerator.php index 8d56e20fa3..8d496c18a1 100644 --- a/src/applications/badges/lipsum/PhabricatorBadgesBadgeTestDataGenerator.php +++ b/src/applications/badges/lipsum/PhabricatorBadgesBadgeTestDataGenerator.php @@ -1,91 +1,91 @@ loadRandomUser(); list($name, $description, $quality, $icon) = $this->newLoot(); $xactions = array(); $xactions[] = array( 'type' => 'name', 'value' => $name, ); $xactions[] = array( 'type' => 'description', 'value' => $description, ); $xactions[] = array( 'type' => 'quality', 'value' => (string)$quality, ); $xactions[] = array( 'type' => 'icon', 'value' => $icon, ); $params = array( 'transactions' => $xactions, ); - $result = id(new ConduitCall('badges.edit', $params)) + $result = id(new ConduitCall('badge.edit', $params)) ->setUser($author) ->execute(); return $result['object']['phid']; } private function newLoot() { $drop = id(new PhabricatorBadgesLootContextFreeGrammar()) ->generate(); $drop = preg_replace_callback( '/<(\d+)-(\d+)>/', array($this, 'rollDropValue'), $drop); $effect_pattern = '/\s*\(([^)]+)\)/'; $matches = null; if (preg_match_all($effect_pattern, $drop, $matches)) { $description = $matches[1]; $description = implode("\n", $description); } else { $description = ''; } $drop = preg_replace($effect_pattern, '', $drop); $quality_map = PhabricatorBadgesQuality::getQualityMap(); shuffle($quality_map); $quality = head($quality_map); $rarity = $quality['rarity']; $icon_map = id(new PhabricatorBadgesIconSet())->getIcons(); shuffle($icon_map); $icon_map = head($icon_map); $icon = $icon_map->getKey(); return array($drop, $description, $rarity, $icon); } public function rollDropValue($matches) { $min = (int)$matches[1]; $max = (int)$matches[2]; return mt_rand($min, $max); } } diff --git a/src/applications/badges/query/PhabricatorBadgesSearchEngine.php b/src/applications/badges/query/PhabricatorBadgesSearchEngine.php index 4db0cdd979..6e84c30bc9 100644 --- a/src/applications/badges/query/PhabricatorBadgesSearchEngine.php +++ b/src/applications/badges/query/PhabricatorBadgesSearchEngine.php @@ -1,156 +1,157 @@ setLabel(pht('Name Contains')) ->setKey('name') ->setDescription(pht('Search for badges by name substring.')), id(new PhabricatorSearchCheckboxesField()) ->setKey('qualities') ->setLabel(pht('Quality')) + ->setEnableForConduit(false) ->setOptions(PhabricatorBadgesQuality::getDropdownQualityMap()), id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setLabel(pht('Status')) ->setOptions( id(new PhabricatorBadgesBadge()) ->getStatusNameMap()), ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['statuses']) { $query->withStatuses($map['statuses']); } if ($map['qualities']) { $query->withQualities($map['qualities']); } if ($map['name'] !== null) { $query->withNameNgrams($map['name']); } return $query; } protected function getURI($path) { return '/badges/'.$path; } protected function getBuiltinQueryNames() { $names = array(); $names['open'] = pht('Active Badges'); $names['all'] = pht('All Badges'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'open': return $query->setParameter( 'statuses', array( PhabricatorBadgesBadge::STATUS_ACTIVE, )); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $badges, PhabricatorSavedQuery $query) { $phids = array(); return $phids; } protected function renderResultList( array $badges, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($badges, 'PhabricatorBadgesBadge'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView()); foreach ($badges as $badge) { $quality_name = PhabricatorBadgesQuality::getQualityName( $badge->getQuality()); $mini_badge = id(new PHUIBadgeMiniView()) ->setHeader($badge->getName()) ->setIcon($badge->getIcon()) ->setQuality($badge->getQuality()); $item = id(new PHUIObjectItemView()) ->setHeader($badge->getName()) ->setBadge($mini_badge) ->setHref('/badges/view/'.$badge->getID().'/') ->addAttribute($quality_name) ->addAttribute($badge->getFlavor()); if ($badge->isArchived()) { $item->setDisabled(true); $item->addIcon('fa-ban', pht('Archived')); } $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No badges found.')); return $result; } protected function getNewUserBody() { $create_button = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Create a Badge')) ->setHref('/badges/create/') ->setColor(PHUIButtonView::GREEN); $icon = $this->getApplication()->getIcon(); $app_name = $this->getApplication()->getName(); $view = id(new PHUIBigInfoView()) ->setIcon($icon) ->setTitle(pht('Welcome to %s', $app_name)) ->setDescription( pht('Badges let you award and distinguish special users '. 'throughout your install.')) ->addAction($create_button); return $view; } } diff --git a/src/applications/search/field/PhabricatorSearchField.php b/src/applications/search/field/PhabricatorSearchField.php index 099fbdcc51..1a038ec665 100644 --- a/src/applications/search/field/PhabricatorSearchField.php +++ b/src/applications/search/field/PhabricatorSearchField.php @@ -1,407 +1,422 @@ key = $key; return $this; } /** * Get the field's key. * * @return string Unique key for this field. * @task config */ public function getKey() { return $this->key; } /** * Set a human-readable label for the field. * * This should be a short text string, like "Reviewers" or "Colors". * * @param string Short, human-readable field label. * @return this * task config */ public function setLabel($label) { $this->label = $label; return $this; } /** * Get the field's human-readable label. * * @return string Short, human-readable field label. * @task config */ public function getLabel() { return $this->label; } /** * Set the acting viewer. * * Engines do not need to do this explicitly; it will be done on their * behalf by the caller. * * @param PhabricatorUser Viewer. * @return this * @task config */ public function setViewer(PhabricatorUser $viewer) { $this->viewer = $viewer; return $this; } /** * Get the acting viewer. * * @return PhabricatorUser Viewer. * @task config */ public function getViewer() { return $this->viewer; } /** * Provide alternate field aliases, usually more human-readable versions * of the key. * * These aliases can be used when building GET requests, so you can provide * an alias like `authors` to let users write `&authors=alincoln` instead of * `&authorPHIDs=alincoln`. This is a little easier to use. * * @param list List of aliases for this field. * @return this * @task config */ public function setAliases(array $aliases) { $this->aliases = $aliases; return $this; } /** * Get aliases for this field. * * @return list List of aliases for this field. * @task config */ public function getAliases() { return $this->aliases; } /** * Provide an alternate field key for Conduit. * * This can allow you to choose a more usable key for API endpoints. * If no key is provided, the main key is used. * * @param string Alternate key for Conduit. * @return this * @task config */ public function setConduitKey($conduit_key) { $this->conduitKey = $conduit_key; return $this; } /** * Get the field key for use in Conduit. * * @return string Conduit key for this field. * @task config */ public function getConduitKey() { if ($this->conduitKey !== null) { return $this->conduitKey; } return $this->getKey(); } /** * Set a human-readable description for this field. * * @param string Human-readable description. * @return this * @task config */ public function setDescription($description) { $this->description = $description; return $this; } /** * Get this field's human-readable description. * * @return string|null Human-readable description. * @task config */ public function getDescription() { return $this->description; } /** * Hide this field from the web UI. * * @param bool True to hide the field from the web UI. * @return this * @task config */ public function setIsHidden($is_hidden) { $this->isHidden = $is_hidden; return $this; } /** * Should this field be hidden from the web UI? * * @return bool True to hide the field in the web UI. * @task config */ public function getIsHidden() { return $this->isHidden; } /* -( Handling Errors )---------------------------------------------------- */ protected function addError($short, $long) { $this->errors[] = array($short, $long); return $this; } public function getErrors() { return $this->errors; } protected function validateControlValue($value) { return; } protected function getShortError() { $error = head($this->getErrors()); if ($error) { return head($error); } return null; } /* -( Reading and Writing Field Values )----------------------------------- */ public function readValueFromRequest(AphrontRequest $request) { $check = array_merge(array($this->getKey()), $this->getAliases()); foreach ($check as $key) { if ($this->getValueExistsInRequest($request, $key)) { return $this->getValueFromRequest($request, $key); } } return $this->getDefaultValue(); } protected function getValueExistsInRequest(AphrontRequest $request, $key) { return $request->getExists($key); } abstract protected function getValueFromRequest( AphrontRequest $request, $key); public function readValueFromSavedQuery(PhabricatorSavedQuery $saved) { $value = $saved->getParameter( $this->getKey(), $this->getDefaultValue()); $this->value = $this->didReadValueFromSavedQuery($value); $this->validateControlValue($value); return $this; } protected function didReadValueFromSavedQuery($value) { return $value; } public function getValue() { return $this->value; } protected function getValueForControl() { return $this->value; } protected function getDefaultValue() { return null; } public function getValueForQuery($value) { return $value; } /* -( Rendering Controls )------------------------------------------------- */ protected function newControl() { throw new PhutilMethodNotImplementedException(); } protected function renderControl() { if ($this->getIsHidden()) { return null; } $control = $this->newControl(); if (!$control) { return null; } // TODO: We should `setError($this->getShortError())` here, but it looks // terrible in the form layout. return $control ->setValue($this->getValueForControl()) ->setName($this->getKey()) ->setLabel($this->getLabel()); } public function appendToForm(AphrontFormView $form) { $control = $this->renderControl(); if ($control !== null) { $form->appendControl($this->renderControl()); } return $this; } /* -( Integration with Conduit )------------------------------------------- */ /** * @task conduit */ final public function getConduitParameterType() { + if (!$this->getEnableForConduit()) { + return false; + } + $type = $this->newConduitParameterType(); if ($type) { $type->setViewer($this->getViewer()); } return $type; } protected function newConduitParameterType() { return null; } public function getValueExistsInConduitRequest(array $constraints) { return $this->getConduitParameterType()->getExists( $constraints, $this->getConduitKey()); } public function readValueFromConduitRequest( array $constraints, $strict = true) { return $this->getConduitParameterType()->getValue( $constraints, $this->getConduitKey(), $strict); } public function getValidConstraintKeys() { return $this->getConduitParameterType()->getKeys( $this->getConduitKey()); } + final public function setEnableForConduit($enable) { + $this->enableForConduit = $enable; + return $this; + } + + final public function getEnableForConduit() { + return $this->enableForConduit; + } + /* -( Utility Methods )----------------------------------------------------- */ /** * Read a list of items from the request, in either array format or string * format: * * list[]=item1&list[]=item2 * list=item1,item2 * * This provides flexibility when constructing URIs, especially from external * sources. * * @param AphrontRequest Request to read strings from. * @param string Key to read in the request. * @return list List of values. * @task utility */ protected function getListFromRequest( AphrontRequest $request, $key) { $list = $request->getArr($key, null); if ($list === null) { $list = $request->getStrList($key); } if (!$list) { return array(); } return $list; } }