1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Update Phurl for modular transactions

Summary: Ref T6049. This moves Phurl to modular transactions.

Test Plan: Everything works here, add phurl, edit phurl, use phurl. Test various error states. Left a TODO on the validate dupe keys, not sure how to implement that in modular-land.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T6049

Differential Revision: https://secure.phabricator.com/D17405
This commit is contained in:
Chad Little 2017-02-24 08:27:35 -08:00
parent 89d1403fe8
commit d38ee2d79a
10 changed files with 304 additions and 431 deletions

View file

@ -3380,16 +3380,20 @@ phutil_register_library_map(array(
'PhabricatorPhurlShortURLDefaultController' => 'applications/phurl/controller/PhabricatorPhurlShortURLDefaultController.php',
'PhabricatorPhurlURL' => 'applications/phurl/storage/PhabricatorPhurlURL.php',
'PhabricatorPhurlURLAccessController' => 'applications/phurl/controller/PhabricatorPhurlURLAccessController.php',
'PhabricatorPhurlURLAliasTransaction' => 'applications/phurl/xaction/PhabricatorPhurlURLAliasTransaction.php',
'PhabricatorPhurlURLCommentController' => 'applications/phurl/controller/PhabricatorPhurlURLCommentController.php',
'PhabricatorPhurlURLCreateCapability' => 'applications/phurl/capability/PhabricatorPhurlURLCreateCapability.php',
'PhabricatorPhurlURLDatasource' => 'applications/phurl/typeahead/PhabricatorPhurlURLDatasource.php',
'PhabricatorPhurlURLDescriptionTransaction' => 'applications/phurl/xaction/PhabricatorPhurlURLDescriptionTransaction.php',
'PhabricatorPhurlURLEditConduitAPIMethod' => 'applications/phurl/conduit/PhabricatorPhurlURLEditConduitAPIMethod.php',
'PhabricatorPhurlURLEditController' => 'applications/phurl/controller/PhabricatorPhurlURLEditController.php',
'PhabricatorPhurlURLEditEngine' => 'applications/phurl/editor/PhabricatorPhurlURLEditEngine.php',
'PhabricatorPhurlURLEditor' => 'applications/phurl/editor/PhabricatorPhurlURLEditor.php',
'PhabricatorPhurlURLListController' => 'applications/phurl/controller/PhabricatorPhurlURLListController.php',
'PhabricatorPhurlURLLongURLTransaction' => 'applications/phurl/xaction/PhabricatorPhurlURLLongURLTransaction.php',
'PhabricatorPhurlURLMailReceiver' => 'applications/phurl/mail/PhabricatorPhurlURLMailReceiver.php',
'PhabricatorPhurlURLNameNgrams' => 'applications/phurl/storage/PhabricatorPhurlURLNameNgrams.php',
'PhabricatorPhurlURLNameTransaction' => 'applications/phurl/xaction/PhabricatorPhurlURLNameTransaction.php',
'PhabricatorPhurlURLPHIDType' => 'applications/phurl/phid/PhabricatorPhurlURLPHIDType.php',
'PhabricatorPhurlURLQuery' => 'applications/phurl/query/PhabricatorPhurlURLQuery.php',
'PhabricatorPhurlURLReplyHandler' => 'applications/phurl/mail/PhabricatorPhurlURLReplyHandler.php',
@ -3398,6 +3402,7 @@ phutil_register_library_map(array(
'PhabricatorPhurlURLTransaction' => 'applications/phurl/storage/PhabricatorPhurlURLTransaction.php',
'PhabricatorPhurlURLTransactionComment' => 'applications/phurl/storage/PhabricatorPhurlURLTransactionComment.php',
'PhabricatorPhurlURLTransactionQuery' => 'applications/phurl/query/PhabricatorPhurlURLTransactionQuery.php',
'PhabricatorPhurlURLTransactionType' => 'applications/phurl/xaction/PhabricatorPhurlURLTransactionType.php',
'PhabricatorPhurlURLViewController' => 'applications/phurl/controller/PhabricatorPhurlURLViewController.php',
'PhabricatorPinnedApplicationsSetting' => 'applications/settings/setting/PhabricatorPinnedApplicationsSetting.php',
'PhabricatorPirateEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorPirateEnglishTranslation.php',
@ -8545,24 +8550,29 @@ phutil_register_library_map(array(
'PhabricatorNgramsInterface',
),
'PhabricatorPhurlURLAccessController' => 'PhabricatorPhurlController',
'PhabricatorPhurlURLAliasTransaction' => 'PhabricatorPhurlURLTransactionType',
'PhabricatorPhurlURLCommentController' => 'PhabricatorPhurlController',
'PhabricatorPhurlURLCreateCapability' => 'PhabricatorPolicyCapability',
'PhabricatorPhurlURLDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorPhurlURLDescriptionTransaction' => 'PhabricatorPhurlURLTransactionType',
'PhabricatorPhurlURLEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'PhabricatorPhurlURLEditController' => 'PhabricatorPhurlController',
'PhabricatorPhurlURLEditEngine' => 'PhabricatorEditEngine',
'PhabricatorPhurlURLEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorPhurlURLListController' => 'PhabricatorPhurlController',
'PhabricatorPhurlURLLongURLTransaction' => 'PhabricatorPhurlURLTransactionType',
'PhabricatorPhurlURLMailReceiver' => 'PhabricatorObjectMailReceiver',
'PhabricatorPhurlURLNameNgrams' => 'PhabricatorSearchNgrams',
'PhabricatorPhurlURLNameTransaction' => 'PhabricatorPhurlURLTransactionType',
'PhabricatorPhurlURLPHIDType' => 'PhabricatorPHIDType',
'PhabricatorPhurlURLQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorPhurlURLReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'PhabricatorPhurlURLSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'PhabricatorPhurlURLSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorPhurlURLTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorPhurlURLTransaction' => 'PhabricatorModularTransaction',
'PhabricatorPhurlURLTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhabricatorPhurlURLTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorPhurlURLTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorPhurlURLViewController' => 'PhabricatorPhurlController',
'PhabricatorPinnedApplicationsSetting' => 'PhabricatorInternalSetting',
'PhabricatorPirateEnglishTranslation' => 'PhutilTranslation',

View file

@ -21,6 +21,10 @@ final class PhabricatorPhurlURLEditEngine
return pht('Configure creation and editing forms in Phurl.');
}
public function isEngineConfigurable() {
return false;
}
protected function newEditableObject() {
return PhabricatorPhurlURL::initializeNewPhurlURL($this->getViewer());
}
@ -73,8 +77,10 @@ final class PhabricatorPhurlURLEditEngine
->setKey('name')
->setLabel(pht('Name'))
->setDescription(pht('URL name.'))
->setIsRequired(true)
->setConduitTypeDescription(pht('New URL name.'))
->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_NAME)
->setTransactionType(
PhabricatorPhurlURLNameTransaction::TRANSACTIONTYPE)
->setValue($object->getName()),
id(new PhabricatorTextEditField())
->setKey('url')
@ -83,11 +89,14 @@ final class PhabricatorPhurlURLEditEngine
->setConduitTypeDescription(pht('New URL.'))
->setValue($object->getLongURL())
->setIsRequired(true)
->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_URL),
->setTransactionType(
PhabricatorPhurlURLLongURLTransaction::TRANSACTIONTYPE),
id(new PhabricatorTextEditField())
->setKey('alias')
->setLabel(pht('Alias'))
->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_ALIAS)
->setIsRequired(true)
->setTransactionType(
PhabricatorPhurlURLAliasTransaction::TRANSACTIONTYPE)
->setDescription(pht('The alias to give the URL.'))
->setConduitTypeDescription(pht('New alias.'))
->setValue($object->getAlias()),
@ -96,7 +105,8 @@ final class PhabricatorPhurlURLEditEngine
->setLabel(pht('Description'))
->setDescription(pht('URL long description.'))
->setConduitTypeDescription(pht('New URL description.'))
->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION)
->setTransactionType(
PhabricatorPhurlURLDescriptionTransaction::TRANSACTIONTYPE)
->setValue($object->getDescription()),
);
}

View file

@ -11,14 +11,20 @@ final class PhabricatorPhurlURLEditor
return pht('Phurl');
}
public function getCreateObjectTitle($author, $object) {
return pht('%s created this URL.', $author);
}
public function getCreateObjectTitleForFeed($author, $object) {
return pht('%s created %s.', $author, $object);
}
protected function supportsSearch() {
return true;
}
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = PhabricatorPhurlURLTransaction::TYPE_NAME;
$types[] = PhabricatorPhurlURLTransaction::TYPE_URL;
$types[] = PhabricatorPhurlURLTransaction::TYPE_ALIAS;
$types[] = PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION;
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
@ -26,160 +32,18 @@ final class PhabricatorPhurlURLEditor
return $types;
}
protected function getCustomTransactionOldValue(
protected function shouldSendMail(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorPhurlURLTransaction::TYPE_NAME:
return $object->getName();
case PhabricatorPhurlURLTransaction::TYPE_URL:
return $object->getLongURL();
case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
return $object->getAlias();
case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION:
return $object->getDescription();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorPhurlURLTransaction::TYPE_NAME:
case PhabricatorPhurlURLTransaction::TYPE_URL:
case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION:
return $xaction->getNewValue();
case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
if (!strlen($xaction->getNewValue())) {
return null;
}
return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorPhurlURLTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
return;
case PhabricatorPhurlURLTransaction::TYPE_URL:
$object->setLongURL($xaction->getNewValue());
return;
case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
$object->setAlias($xaction->getNewValue());
return;
case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION:
$object->setDescription($xaction->getNewValue());
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorPhurlURLTransaction::TYPE_NAME:
case PhabricatorPhurlURLTransaction::TYPE_URL:
case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
return true;
}
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
$overdrawn = $this->validateIsTextFieldTooLong(
$object->getName(),
$xactions,
64);
if ($overdrawn) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Alias Too Long'),
pht('The alias can be no longer than 64 characters.'),
nonempty(last($xactions), null));
}
foreach ($xactions as $xaction) {
if ($xaction->getOldValue() != $xaction->getNewValue()) {
$new_alias = $xaction->getNewValue();
$debug_alias = new PHUIInvisibleCharacterView($new_alias);
if (!preg_match('/[a-zA-Z]/', $new_alias)) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid Alias'),
pht('The alias you provided (%s) must contain at least one '.
'letter.',
$debug_alias),
$xaction);
}
if (preg_match('/[^a-z0-9]/i', $new_alias)) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid Alias'),
pht('The alias you provided (%s) may only contain letters and '.
'numbers.',
$debug_alias),
$xaction);
}
}
}
break;
case PhabricatorPhurlURLTransaction::TYPE_URL:
$missing = $this->validateIsEmptyTextField(
$object->getLongURL(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('URL path is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
foreach ($xactions as $xaction) {
if ($xaction->getOldValue() != $xaction->getNewValue()) {
$protocols = PhabricatorEnv::getEnvConfig('uri.allowed-protocols');
$uri = new PhutilURI($xaction->getNewValue());
if (!isset($protocols[$uri->getProtocol()])) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid URL'),
pht('The protocol of the URL is invalid.'),
null);
}
}
}
break;
}
return $errors;
public function getMailTagsMap() {
return array(
PhabricatorPhurlURLTransaction::MAILTAG_DETAILS =>
pht(
"A URL's details change."),
);
}
protected function shouldPublishFeedStory(
@ -188,36 +52,17 @@ final class PhabricatorPhurlURLEditor
return true;
}
protected function supportsSearch() {
return true;
}
protected function shouldSendMail(
PhabricatorLiskDAO $object,
array $xactions) {
return true;
}
protected function getMailSubjectPrefix() {
return pht('[Phurl]');
}
protected function getMailTo(PhabricatorLiskDAO $object) {
$phids = array();
$phids[] = $this->getActingAsPHID();
return $phids;
}
public function getMailTagsMap() {
return array(
PhabricatorPhurlURLTransaction::MAILTAG_DETAILS =>
pht(
"A URL's details change."),
);
}
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
$id = $object->getID();
$name = $object->getName();
@ -255,7 +100,7 @@ final class PhabricatorPhurlURLEditor
$errors = array();
$errors[] = new PhabricatorApplicationTransactionValidationError(
PhabricatorPhurlURLTransaction::TYPE_ALIAS,
PhabricatorPhurlURLAliasTransaction::TRANSACTIONTYPE,
pht('Duplicate'),
pht('This alias is already in use.'),
null);

View file

@ -1,12 +1,7 @@
<?php
final class PhabricatorPhurlURLTransaction
extends PhabricatorApplicationTransaction {
const TYPE_NAME = 'phurl.name';
const TYPE_URL = 'phurl.longurl';
const TYPE_ALIAS = 'phurl.alias';
const TYPE_DESCRIPTION = 'phurl.description';
extends PhabricatorModularTransaction {
const MAILTAG_DETAILS = 'phurl-details';
@ -22,14 +17,18 @@ final class PhabricatorPhurlURLTransaction
return new PhabricatorPhurlURLTransactionComment();
}
public function getBaseTransactionClass() {
return 'PhabricatorPhurlURLTransactionType';
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
case self::TYPE_URL:
case self::TYPE_ALIAS:
case self::TYPE_DESCRIPTION:
case PhabricatorPhurlURLNameTransaction::TRANSACTIONTYPE:
case PhabricatorPhurlURLLongURLTransaction::TRANSACTIONTYPE:
case PhabricatorPhurlURLAliasTransaction::TRANSACTIONTYPE:
case PhabricatorPhurlURLDescriptionTransaction::TRANSACTIONTYPE:
$phids[] = $this->getObjectPHID();
break;
}
@ -37,203 +36,13 @@ final class PhabricatorPhurlURLTransaction
return $phids;
}
public function shouldHide() {
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
return ($old === null);
}
return parent::shouldHide();
}
public function getIcon() {
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
case self::TYPE_URL:
case self::TYPE_ALIAS:
case self::TYPE_DESCRIPTION:
return 'fa-pencil';
break;
}
return parent::getIcon();
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$object_phid = $this->getObjectPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created this URL.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s changed the name of the URL from %s to %s.',
$this->renderHandleLink($author_phid),
$old,
$new);
}
case self::TYPE_URL:
if ($old === null) {
return pht(
'%s set the destination of the URL to %s.',
$this->renderHandleLink($author_phid),
$new);
} else {
return pht(
'%s changed the destination of the URL from %s to %s.',
$this->renderHandleLink($author_phid),
$old,
$new);
}
case self::TYPE_ALIAS:
if ($old === null) {
return pht(
'%s set the alias of the URL to %s.',
$this->renderHandleLink($author_phid),
$new);
} else if ($new === null) {
return pht(
'%s removed the alias of the URL.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s changed the alias of the URL from %s to %s.',
$this->renderHandleLink($author_phid),
$old,
$new);
}
case self::TYPE_DESCRIPTION:
return pht(
"%s updated the URL's description.",
$this->renderHandleLink($author_phid));
}
return parent::getTitle();
}
public function getTitleForFeed() {
$author_phid = $this->getAuthorPHID();
$object_phid = $this->getObjectPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
$viewer = $this->getViewer();
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else {
return pht(
'%s changed the name of %s from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old,
$new);
}
case self::TYPE_URL:
if ($old === null) {
return pht(
'%s set the destination of %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$new);
} else {
return pht(
'%s changed the destination of %s from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old,
$new);
}
case self::TYPE_ALIAS:
if ($old === null) {
return pht(
'%s set the alias of %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$new);
} else if ($new === null) {
return pht(
'%s removed the alias of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else {
return pht(
'%s changed the alias of %s from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old,
$new);
}
case self::TYPE_DESCRIPTION:
return pht(
'%s updated the description of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
return parent::getTitleForFeed();
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
case self::TYPE_URL:
case self::TYPE_ALIAS:
case self::TYPE_DESCRIPTION:
return PhabricatorTransactions::COLOR_GREEN;
}
return parent::getColor();
}
public function hasChangeDetails() {
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
return ($this->getOldValue() !== null);
}
return parent::hasChangeDetails();
}
public function renderChangeDetails(PhabricatorUser $viewer) {
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
$old = $this->getOldValue();
$new = $this->getNewValue();
return $this->renderTextCorpusChangeDetails(
$viewer,
$old,
$new);
}
return parent::renderChangeDetails($viewer);
}
public function getMailTags() {
$tags = array();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
case self::TYPE_DESCRIPTION:
case self::TYPE_URL:
case self::TYPE_ALIAS:
case PhabricatorPhurlURLNameTransaction::TRANSACTIONTYPE:
case PhabricatorPhurlURLLongURLTransaction::TRANSACTIONTYPE:
case PhabricatorPhurlURLAliasTransaction::TRANSACTIONTYPE:
case PhabricatorPhurlURLDescriptionTransaction::TRANSACTIONTYPE:
$tags[] = self::MAILTAG_DETAILS;
break;
}

View file

@ -0,0 +1,77 @@
<?php
final class PhabricatorPhurlURLAliasTransaction
extends PhabricatorPhurlURLTransactionType {
const TRANSACTIONTYPE = 'phurl.alias';
public function generateOldValue($object) {
return $object->getAlias();
}
public function applyInternalEffects($object, $value) {
$object->setAlias($value);
}
public function getTitle() {
return pht(
'%s changed the alias from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function getTitleForFeed() {
return pht(
'%s changed the alias of %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getAlias(), $xactions)) {
$errors[] = $this->newRequiredError(
pht('Phurls must have an alias.'));
}
$max_length = $object->getColumnMaximumByteLength('alias');
foreach ($xactions as $xaction) {
$new_alias = $xaction->getNewValue();
// Check length
$new_length = strlen($new_alias);
if ($new_length > $max_length) {
$errors[] = $this->newRequiredError(
pht('The alias can be no longer than %d characters.', $max_length));
}
// Check characters
if ($xaction->getOldValue() != $xaction->getNewValue()) {
$debug_alias = new PHUIInvisibleCharacterView($new_alias);
if (!preg_match('/[a-zA-Z]/', $new_alias)) {
$errors[] = $this->newRequiredError(
pht('The alias you provided (%s) must contain at least one '.
'letter.',
$debug_alias));
}
if (preg_match('/[^a-z0-9]/i', $new_alias)) {
$errors[] = $this->newRequiredError(
pht('The alias you provided (%s) may only contain letters and '.
'numbers.',
$debug_alias));
}
}
}
return $errors;
}
public function getIcon() {
return 'fa-compress';
}
}

View file

@ -0,0 +1,60 @@
<?php
final class PhabricatorPhurlURLDescriptionTransaction
extends PhabricatorPhurlURLTransactionType {
const TRANSACTIONTYPE = 'phurl.description';
public function generateOldValue($object) {
return $object->getDescription();
}
public function applyInternalEffects($object, $value) {
$object->setDescription($value);
}
public function getTitle() {
return pht(
'%s updated the description.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the description for %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function hasChangeDetailView() {
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO PHURL DESCRIPTION');
}
public function newChangeDetailView() {
$viewer = $this->getViewer();
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
->setViewer($viewer)
->setOldText($this->getOldValue())
->setNewText($this->getNewValue());
}
public function newRemarkupChanges() {
$changes = array();
$changes[] = $this->newRemarkupChange()
->setOldValue($this->getOldValue())
->setNewValue($this->getNewValue());
return $changes;
}
public function getIcon() {
return 'fa-file-text-o';
}
}

View file

@ -0,0 +1,59 @@
<?php
final class PhabricatorPhurlURLLongURLTransaction
extends PhabricatorPhurlURLTransactionType {
const TRANSACTIONTYPE = 'phurl.longurl';
public function generateOldValue($object) {
return $object->getLongURL();
}
public function applyInternalEffects($object, $value) {
$object->setLongURL($value);
}
public function getTitle() {
return pht(
'%s changed the destination URL from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function getTitleForFeed() {
return pht(
'%s changed the destination URL %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getLongURL(), $xactions)) {
$errors[] = $this->newRequiredError(
pht('URL path is required'));
}
foreach ($xactions as $xaction) {
if ($xaction->getOldValue() != $xaction->getNewValue()) {
$protocols = PhabricatorEnv::getEnvConfig('uri.allowed-protocols');
$uri = new PhutilURI($xaction->getNewValue());
if (!isset($protocols[$uri->getProtocol()])) {
$errors[] = $this->newRequiredError(
pht('The protocol of the URL is invalid.'));
}
}
}
return $errors;
}
public function getIcon() {
return 'fa-external-link-square';
}
}

View file

@ -0,0 +1,44 @@
<?php
final class PhabricatorPhurlURLNameTransaction
extends PhabricatorPhurlURLTransactionType {
const TRANSACTIONTYPE = 'phurl.name';
public function generateOldValue($object) {
return $object->getName();
}
public function applyInternalEffects($object, $value) {
$object->setName($value);
}
public function getTitle() {
return pht(
'%s changed the name of the URL from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function getTitleForFeed() {
return pht(
'%s changed the name of %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
$errors[] = $this->newRequiredError(
pht('Phurls must have a name.'));
}
return $errors;
}
}

View file

@ -0,0 +1,4 @@
<?php
abstract class PhabricatorPhurlURLTransactionType
extends PhabricatorModularTransactionType {}

View file

@ -2324,51 +2324,6 @@ abstract class PhabricatorApplicationTransactionEditor
return true;
}
/**
* Check that text field input isn't longer than a specified length.
*
* A text field input is invalid if the length of the input is longer than a
* specified length. This length can be determined by the space allotted in
* the database, or given arbitrarily.
* This method is intended to make implementing @{method:validateTransaction}
* more convenient:
*
* $overdrawn = $this->validateIsTextFieldTooLong(
* $object->getName(),
* $xactions,
* $field_length);
*
* This will return `true` if the net effect of the object and transactions
* is a field that is too long.
*
* @param wild Current field value.
* @param list<PhabricatorApplicationTransaction> Transactions editing the
* field.
* @param integer for maximum field length.
* @return bool True if the field will be too long after edits.
*/
protected function validateIsTextFieldTooLong(
$field_value,
array $xactions,
$length) {
if ($xactions) {
$new_value_length = phutil_utf8_strlen(last($xactions)->getNewValue());
if ($new_value_length <= $length) {
return false;
} else {
return true;
}
}
$old_value_length = phutil_utf8_strlen($field_value);
if ($old_value_length <= $length) {
return false;
}
return true;
}
/* -( Implicit CCs )------------------------------------------------------- */