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:
parent
89d1403fe8
commit
d38ee2d79a
10 changed files with 304 additions and 431 deletions
|
@ -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',
|
||||
|
|
|
@ -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()),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
||||
}
|
|
@ -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';
|
||||
}
|
||||
|
||||
}
|
|
@ -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';
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorPhurlURLTransactionType
|
||||
extends PhabricatorModularTransactionType {}
|
|
@ -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 )------------------------------------------------------- */
|
||||
|
||||
|
|
Loading…
Reference in a new issue