Changeset View
Standalone View
src/applications/tokens/storage/PhabricatorTokensToken.php
- This file was added.
| <?php | |||||
| final class PhabricatorTokensToken extends PhabricatorTokensDAO | |||||
| implements | |||||
| PhabricatorPolicyInterface, | |||||
| PhabricatorDestructibleInterface, | |||||
| PhabricatorSubscribableInterface, | |||||
| PhabricatorFlaggableInterface, | |||||
| PhabricatorApplicationTransactionInterface, | |||||
| PhabricatorConduitResultInterface { | |||||
| protected $name; | |||||
| protected $flavor; | |||||
| protected $status; | |||||
| protected $creatorPHID; | |||||
| protected $editPolicy; | |||||
| protected $mailKey; | |||||
| protected $tokenImagePHID; | |||||
| const STATUS_ACTIVE = 'active'; | |||||
| const STATUS_ARCHIVED = 'archived'; | |||||
| protected function getConfiguration() { | |||||
| return array( | |||||
| self::CONFIG_AUX_PHID => true, | |||||
| self::CONFIG_SERIALIZATION => array( | |||||
| 'configData' => self::SERIALIZATION_JSON, | |||||
| ), | |||||
| self::CONFIG_COLUMN_SCHEMA => array( | |||||
| 'name' => 'text64', | |||||
| 'flavor' => 'text128', | |||||
| 'status' => 'text32', | |||||
| 'tokenImagePHID' => 'phid', | |||||
| 'mailKey' => 'bytes20', | |||||
| ), | |||||
| self::CONFIG_KEY_SCHEMA => array( | |||||
| 'key_creator' => array( | |||||
| 'columns' => array('creatorPHID', 'dateModified'), | |||||
| ), | |||||
epriestley: (I don't think any query actually uses this key.) | |||||
| ), | |||||
| ) + parent::getConfiguration(); | |||||
| } | |||||
| public function generatePHID() { | |||||
| return PhabricatorPHID::generateNewPHID( | |||||
| PhabricatorTokensTokenPHIDType::TYPECONST); | |||||
| } | |||||
| public static function initializeNewToken(PhabricatorUser $actor) { | |||||
| $app = id(new PhabricatorApplicationQuery()) | |||||
| ->setViewer($actor) | |||||
| ->withClasses(array('PhabricatorTokensApplication')) | |||||
| ->executeOne(); | |||||
| $edit_policy = | |||||
| $app->getPolicy(PhabricatorTokensDefaultEditCapability::CAPABILITY); | |||||
| $token = id(new self()) | |||||
| ->setCreatorPHID($actor->getPHID()) | |||||
| ->setStatus(self::STATUS_ACTIVE) | |||||
| ->setEditPolicy($edit_policy) | |||||
| ->setTokenImagePHID(''); | |||||
epriestleyUnsubmitted Not Done Inline ActionsThis is sketchy, although probably fine in a rough cut, but maybe leave a TODO. epriestley: This is sketchy, although probably fine in a rough cut, but maybe leave a TODO. | |||||
| return $token; | |||||
| } | |||||
| public function isArchived() { | |||||
| return ($this->getStatus() == self::STATUS_ARCHIVED); | |||||
| } | |||||
| public static function getStatusNameMap() { | |||||
| return array( | |||||
| self::STATUS_ACTIVE => pht('Active'), | |||||
| self::STATUS_ARCHIVED => pht('Archived'), | |||||
| ); | |||||
| } | |||||
| public function getTokenImageURI() { | |||||
| return $this->getTokenImageFile()->getBestURI(); | |||||
| } | |||||
| public function attachTokenImageFile(PhabricatorFile $file) { | |||||
| $this->tokenImageFile = $file; | |||||
| return $this; | |||||
| } | |||||
| public function getTokenImageFile() { | |||||
| return $this->assertAttached($this->tokenImageFile); | |||||
| } | |||||
| public function getViewURI() { | |||||
| return '/tokens/view/'.$this->getID().'/'; | |||||
| } | |||||
| public function save() { | |||||
| if (!$this->getMailKey()) { | |||||
| $this->setMailKey(Filesystem::readRandomCharacters(20)); | |||||
| } | |||||
| return parent::save(); | |||||
| } | |||||
| /* -( PhabricatorPolicyInterface Implementation )-------------------------- */ | |||||
| public function getCapabilities() { | |||||
| return array( | |||||
| PhabricatorPolicyCapability::CAN_VIEW, | |||||
| PhabricatorPolicyCapability::CAN_EDIT, | |||||
| ); | |||||
| } | |||||
| public function getPolicy($capability) { | |||||
| switch ($capability) { | |||||
| case PhabricatorPolicyCapability::CAN_VIEW: | |||||
| return PhabricatorPolicies::getMostOpenPolicy(); | |||||
| case PhabricatorPolicyCapability::CAN_EDIT: | |||||
| return $this->getEditPolicy(); | |||||
| } | |||||
| } | |||||
| public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { | |||||
| return false; | |||||
| } | |||||
| public function describeAutomaticCapability($capability) { | |||||
| return null; | |||||
| } | |||||
| /* -( PhabricatorDestructibleInterface )----------------------------------- */ | |||||
| public function destroyObjectPermanently( | |||||
| PhabricatorDestructionEngine $engine) { | |||||
| $this->openTransaction(); | |||||
| $tokens = id(new self()) | |||||
| ->loadAllWhere('tokenPHID = %s', $this->getPHID()); | |||||
| foreach ($tokens as $token) { | |||||
| $token->delete(); | |||||
| } | |||||
epriestleyUnsubmitted Not Done Inline ActionsThis has no effect, and is the same as $this->delete(). However, this probably should remove all PhabricatorTokenGiven rows for the token, and should somehow regenerate all PhabricatorTokenCount rows for affected objects. Neither of these tables are edge tables, so they won't be handled automatically. epriestley: This has no effect, and is the same as `$this->delete()`.
However, this probably //should//… | |||||
| $this->delete(); | |||||
| $this->saveTransaction(); | |||||
| } | |||||
| /* -( PhabricatorApplicationTransactionInterface )------------------------- */ | |||||
| public function getApplicationTransactionEditor() { | |||||
| return new PhabricatorTokenEditor(); | |||||
| } | |||||
| public function getApplicationTransactionObject() { | |||||
| return $this; | |||||
| } | |||||
| public function getApplicationTransactionTemplate() { | |||||
| return new PhabricatorTokensTransaction(); | |||||
| } | |||||
| public function willRenderTimeline( | |||||
| PhabricatorApplicationTransactionView $timeline, | |||||
| AphrontRequest $request) { | |||||
| return $timeline; | |||||
| } | |||||
| /* -( PhabricatorSubscribableInterface Implementation )-------------------- */ | |||||
| public function isAutomaticallySubscribed($phid) { | |||||
| return ($this->creatorPHID == $phid); | |||||
| } | |||||
| /* -( PhabricatorConduitResultInterface )---------------------------------- */ | |||||
| public function getFieldSpecificationsForConduit() { | |||||
| return array( | |||||
| id(new PhabricatorConduitSearchFieldSpecification()) | |||||
| ->setKey('name') | |||||
| ->setType('string') | |||||
| ->setDescription(pht('The name of the token.')), | |||||
| id(new PhabricatorConduitSearchFieldSpecification()) | |||||
| ->setKey('flavor') | |||||
| ->setType('string') | |||||
| ->setDescription(pht('Token flavor.')), | |||||
| id(new PhabricatorConduitSearchFieldSpecification()) | |||||
| ->setKey('status') | |||||
| ->setType('string') | |||||
| ->setDescription(pht('Archived or active status.')), | |||||
| ); | |||||
| } | |||||
| public function getFieldValuesForConduit() { | |||||
| return array( | |||||
epriestleyUnsubmitted Not Done Inline ActionsThe most useful thing we could return here is probably image with filePHID and viewURI? (Or maybe this is images with a list of different sizes, although presumably we'll just use one size and tell users to upload 2x.) epriestley: The most useful thing we could return here is probably `image` with `filePHID` and `viewURI`? | |||||
| 'name' => $this->getName(), | |||||
| 'flavor' => $this->getFlavor(), | |||||
| 'status' => $this->getStatus(), | |||||
epriestleyUnsubmitted Not Done Inline ActionsI've been inching toward providing richer result sets for values like "status" -- for example, Maniphest returns the constant, but also the human-readable name, color, etc. Although it's unlikely that we'll add colors or other special things to this, we do have at least two values we can return (constant, human-readable name). And if we return a dictionary instead of a single string, we can add more stuff later more easily. One alternative is to return only the constant and then provide a separate query for getting details about available statuses, but that feels a little clumsy/YAGNI for simple applications like this. Another alternative is to provide extra information later as an attachment instead of on the main response. That's very tacked-on, but doesn't break backward compatibility. A third alternative is to break backward compatibility if we want to add more data later. epriestley: I've been inching toward providing richer result sets for values like "status" -- for example… | |||||
| ); | |||||
| } | |||||
| public function getConduitSearchAttachments() { | |||||
| return array(); | |||||
| } | |||||
| } | |||||
(I don't think any query actually uses this key.)