Page MenuHomestyx hydra

No OneTemporary

diff --git a/resources/sql/autopatches/20151130.phurl.mailkey.1.sql b/resources/sql/autopatches/20151130.phurl.mailkey.1.sql
new file mode 100644
index 0000000000..67e9e25586
--- /dev/null
+++ b/resources/sql/autopatches/20151130.phurl.mailkey.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_phurl.phurl_url
+ ADD mailKey binary(20) NOT NULL;
diff --git a/resources/sql/autopatches/20151130.phurl.mailkey.2.php b/resources/sql/autopatches/20151130.phurl.mailkey.2.php
new file mode 100644
index 0000000000..93c7e7a4d2
--- /dev/null
+++ b/resources/sql/autopatches/20151130.phurl.mailkey.2.php
@@ -0,0 +1,18 @@
+<?php
+
+$table = new PhabricatorPhurlURL();
+$conn_w = $table->establishConnection('w');
+$iterator = new LiskMigrationIterator($table);
+foreach ($iterator as $url) {
+ $id = $url->getID();
+
+ echo pht('Adding mail key for Phurl %d...', $id);
+ echo "\n";
+
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET mailKey = %s WHERE id = %d',
+ $table->getTableName(),
+ Filesystem::readRandomCharacters(20),
+ $id);
+}
diff --git a/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php b/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php
index 712478c839..c36100f12b 100644
--- a/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php
+++ b/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php
@@ -1,267 +1,265 @@
<?php
final class PhabricatorPhurlURLEditor
extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorPhurlApplication';
}
public function getEditorObjectsDescription() {
return pht('Phurl');
}
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;
return $types;
}
protected function getCustomTransactionOldValue(
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) {
$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();
if (!preg_match('/[a-zA-Z]/', $new_alias)) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid Alias'),
pht('The alias must contain at least one letter.'),
$xaction);
}
if (preg_match('/[^a-z0-9]/i', $new_alias)) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid Alias'),
pht('The alias may only contain letters and numbers.'),
$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;
}
protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object,
array $xactions) {
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();
if ($object->getPHID()) {
$phids[] = $object->getPHID();
}
$phids[] = $this->getActingAsPHID();
$phids = array_unique($phids);
return $phids;
}
public function getMailTagsMap() {
return array(
- PhabricatorPhurlURLTransaction::MAILTAG_CONTENT =>
+ PhabricatorPhurlURLTransaction::MAILTAG_DETAILS =>
pht(
- "A URL's name or path changes."),
- PhabricatorPhurlURLTransaction::MAILTAG_OTHER =>
- pht('Other event activity not listed above occurs.'),
+ "A URL's details change."),
);
}
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
$id = $object->getID();
$name = $object->getName();
return id(new PhabricatorMetaMTAMail())
->setSubject("U{$id}: {$name}")
->addHeader('Thread-Topic', "U{$id}: ".$object->getName());
}
protected function buildMailBody(
PhabricatorLiskDAO $object,
array $xactions) {
$description = $object->getDescription();
$body = parent::buildMailBody($object, $xactions);
if (strlen($description)) {
$body->addRemarkupSection(
pht('URL DESCRIPTION'),
$object->getDescription());
}
$body->addLinkSection(
pht('URL DETAIL'),
PhabricatorEnv::getProductionURI('/U'.$object->getID()));
return $body;
}
protected function didCatchDuplicateKeyException(
PhabricatorLiskDAO $object,
array $xactions,
Exception $ex) {
$errors = array();
$errors[] = new PhabricatorApplicationTransactionValidationError(
PhabricatorPhurlURLTransaction::TYPE_ALIAS,
pht('Duplicate'),
pht('This alias is already in use.'),
null);
throw new PhabricatorApplicationTransactionValidationException($errors);
}
}
diff --git a/src/applications/phurl/storage/PhabricatorPhurlURL.php b/src/applications/phurl/storage/PhabricatorPhurlURL.php
index 34a143bc90..7df1d241a7 100644
--- a/src/applications/phurl/storage/PhabricatorPhurlURL.php
+++ b/src/applications/phurl/storage/PhabricatorPhurlURL.php
@@ -1,194 +1,204 @@
<?php
final class PhabricatorPhurlURL extends PhabricatorPhurlDAO
implements PhabricatorPolicyInterface,
PhabricatorProjectInterface,
PhabricatorApplicationTransactionInterface,
PhabricatorSubscribableInterface,
PhabricatorTokenReceiverInterface,
PhabricatorDestructibleInterface,
PhabricatorMentionableInterface,
PhabricatorFlaggableInterface,
PhabricatorSpacesInterface {
protected $name;
protected $alias;
protected $longURL;
protected $description;
protected $viewPolicy;
protected $editPolicy;
protected $authorPHID;
protected $spacePHID;
+ protected $mailKey;
+
const DEFAULT_ICON = 'fa-compress';
public static function initializeNewPhurlURL(PhabricatorUser $actor) {
$app = id(new PhabricatorApplicationQuery())
->setViewer($actor)
->withClasses(array('PhabricatorPhurlApplication'))
->executeOne();
return id(new PhabricatorPhurlURL())
->setAuthorPHID($actor->getPHID())
->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())
->setEditPolicy($actor->getPHID())
->setSpacePHID($actor->getDefaultSpacePHID());
}
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text',
'alias' => 'sort64?',
'longURL' => 'text',
'description' => 'text',
+ 'mailKey' => 'bytes20',
),
self::CONFIG_KEY_SCHEMA => array(
'key_instance' => array(
'columns' => array('alias'),
'unique' => true,
),
'key_author' => array(
'columns' => array('authorPHID'),
),
),
) + parent::getConfiguration();
}
+ public function save() {
+ if (!$this->getMailKey()) {
+ $this->setMailKey(Filesystem::readRandomCharacters(20));
+ }
+ return parent::save();
+ }
+
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPhurlURLPHIDType::TYPECONST);
}
public function getMonogram() {
return 'U'.$this->getID();
}
public function getURI() {
$uri = '/'.$this->getMonogram();
return $uri;
}
public function isValid() {
$allowed_protocols = PhabricatorEnv::getEnvConfig('uri.allowed-protocols');
$uri = new PhutilURI($this->getLongURL());
return isset($allowed_protocols[$uri->getProtocol()]);
}
public function getDisplayName() {
if ($this->getName()) {
return $this->getName();
} else {
return $this->getLongURL();
}
}
public function getRedirectURI() {
if (strlen($this->getAlias())) {
return '/u/'.$this->getAlias();
} else {
return '/u/'.$this->getID();
}
}
/* -( 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) {
$user_phid = $this->getAuthorPHID();
if ($user_phid) {
$viewer_phid = $viewer->getPHID();
if ($viewer_phid == $user_phid) {
return true;
}
}
return false;
}
public function describeAutomaticCapability($capability) {
return pht('The owner of a URL can always view and edit it.');
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
public function getApplicationTransactionEditor() {
return new PhabricatorPhurlURLEditor();
}
public function getApplicationTransactionObject() {
return $this;
}
public function getApplicationTransactionTemplate() {
return new PhabricatorPhurlURLTransaction();
}
public function willRenderTimeline(
PhabricatorApplicationTransactionView $timeline,
AphrontRequest $request) {
return $timeline;
}
/* -( PhabricatorSubscribableInterface )----------------------------------- */
public function isAutomaticallySubscribed($phid) {
return ($phid == $this->getAuthorPHID());
}
public function shouldShowSubscribersProperty() {
return true;
}
public function shouldAllowSubscription($phid) {
return true;
}
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */
public function getUsersToNotifyOfTokenGiven() {
return array($this->getAuthorPHID());
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$this->saveTransaction();
}
/* -( PhabricatorSpacesInterface )----------------------------------------- */
public function getSpacePHID() {
return $this->spacePHID;
}
}
diff --git a/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php b/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php
index 6d275bcefb..d520b30518 100644
--- a/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php
+++ b/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php
@@ -1,244 +1,243 @@
<?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';
- const MAILTAG_CONTENT = 'phurl:content';
- const MAILTAG_OTHER = 'phurl:other';
+ const MAILTAG_DETAILS = 'phurl-details';
public function getApplicationName() {
return 'phurl';
}
public function getApplicationTransactionType() {
return PhabricatorPhurlURLPHIDType::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return new PhabricatorPhurlURLTransactionComment();
}
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:
$phids[] = $this->getObjectPHID();
break;
}
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:
- $tags[] = self::MAILTAG_CONTENT;
+ $tags[] = self::MAILTAG_DETAILS;
break;
}
return $tags;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Mar 16, 11:26 PM (1 d, 3 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
963590
Default Alt Text
(22 KB)

Event Timeline