mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
DRAFT - throw together Phurl skeleton.
Summary: DRAFT - throw together Phurl skeleton. Test Plan: The idea is that `some/long/url` will become `install/Udet4d` and can be viewed and edited at `install/Udet4d/view` and `install/Udet4d/edit`, respectively? Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: joshuaspence, chad, epriestley, Korvin Maniphest Tasks: T6049 Differential Revision: https://secure.phabricator.com/D13681
This commit is contained in:
parent
2ada395ea9
commit
930b6fec25
24 changed files with 1463 additions and 0 deletions
10
resources/sql/autopatches/20150721.phurl.1.url.sql
Normal file
10
resources/sql/autopatches/20150721.phurl.1.url.sql
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phurl.phurl_url (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
phid VARBINARY(64) NOT NULL,
|
||||||
|
name VARCHAR(255) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
longURL VARCHAR(2047) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
description VARCHAR(2047) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
viewPolicy VARBINARY(64) NOT NULL,
|
||||||
|
editPolicy VARBINARY(64) NOT NULL,
|
||||||
|
spacePHID varbinary(64) DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
19
resources/sql/autopatches/20150721.phurl.2.xaction.sql
Normal file
19
resources/sql/autopatches/20150721.phurl.2.xaction.sql
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phurl.phurl_urltransaction (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
phid VARBINARY(64) NOT NULL,
|
||||||
|
authorPHID VARBINARY(64) NOT NULL,
|
||||||
|
objectPHID VARBINARY(64) NOT NULL,
|
||||||
|
viewPolicy VARBINARY(64) NOT NULL,
|
||||||
|
editPolicy VARBINARY(64) NOT NULL,
|
||||||
|
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||||
|
commentVersion INT UNSIGNED NOT NULL,
|
||||||
|
transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_phid` (`phid`),
|
||||||
|
KEY `key_object` (`objectPHID`)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,16 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phurl.phurl_urltransaction_comment (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
phid VARBINARY(64) NOT NULL,
|
||||||
|
transactionPHID VARBINARY(64) DEFAULT NULL,
|
||||||
|
authorPHID VARBINARY(64) NOT NULL,
|
||||||
|
viewPolicy VARBINARY(64) NOT NULL,
|
||||||
|
editPolicy VARBINARY(64) NOT NULL,
|
||||||
|
commentVersion INT UNSIGNED NOT NULL,
|
||||||
|
content LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
isDeleted TINYINT(1) NOT NULL,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_phid` (`phid`),
|
||||||
|
UNIQUE KEY `key_version` (`transactionPHID`,`commentVersion`)
|
||||||
|
) ENGINE=InnoDB COLLATE {$COLLATE_TEXT}
|
3
resources/sql/autopatches/20150721.phurl.4.url.sql
Normal file
3
resources/sql/autopatches/20150721.phurl.4.url.sql
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_phurl.phurl_url
|
||||||
|
ADD dateCreated int unsigned NOT NULL,
|
||||||
|
ADD dateModified int unsigned NOT NULL;
|
16
resources/sql/autopatches/20150721.phurl.5.edge.sql
Normal file
16
resources/sql/autopatches/20150721.phurl.5.edge.sql
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phurl.edge (
|
||||||
|
src VARBINARY(64) NOT NULL,
|
||||||
|
type INT UNSIGNED NOT NULL,
|
||||||
|
dst VARBINARY(64) NOT NULL,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
seq INT UNSIGNED NOT NULL,
|
||||||
|
dataID INT UNSIGNED,
|
||||||
|
PRIMARY KEY (src, type, dst),
|
||||||
|
KEY `src` (src, type, dateCreated, seq),
|
||||||
|
UNIQUE KEY `key_dst` (dst, type, src)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||||
|
|
||||||
|
CREATE TABLE {$NAMESPACE}_phurl.edgedata (
|
||||||
|
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
data LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
2
resources/sql/autopatches/20150721.phurl.6.alias.sql
Normal file
2
resources/sql/autopatches/20150721.phurl.6.alias.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_phurl.phurl_url
|
||||||
|
ADD alias VARCHAR(64) COLLATE {$COLLATE_SORT};
|
|
@ -0,0 +1,6 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_phurl.phurl_url
|
||||||
|
ADD authorPHID VARBINARY(64) NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_phurl.phurl_url
|
||||||
|
CHANGE description description LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
CHANGE longURL longURL LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};
|
|
@ -2476,6 +2476,21 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPhrequentConfigOptions' => 'applications/phrequent/config/PhabricatorPhrequentConfigOptions.php',
|
'PhabricatorPhrequentConfigOptions' => 'applications/phrequent/config/PhabricatorPhrequentConfigOptions.php',
|
||||||
'PhabricatorPhrictionApplication' => 'applications/phriction/application/PhabricatorPhrictionApplication.php',
|
'PhabricatorPhrictionApplication' => 'applications/phriction/application/PhabricatorPhrictionApplication.php',
|
||||||
'PhabricatorPhrictionConfigOptions' => 'applications/phriction/config/PhabricatorPhrictionConfigOptions.php',
|
'PhabricatorPhrictionConfigOptions' => 'applications/phriction/config/PhabricatorPhrictionConfigOptions.php',
|
||||||
|
'PhabricatorPhurlApplication' => 'applications/phurl/application/PhabricatorPhurlApplication.php',
|
||||||
|
'PhabricatorPhurlController' => 'applications/phurl/controller/PhabricatorPhurlController.php',
|
||||||
|
'PhabricatorPhurlDAO' => 'applications/phurl/storage/PhabricatorPhurlDAO.php',
|
||||||
|
'PhabricatorPhurlSchemaSpec' => 'applications/phurl/storage/PhabricatorPhurlSchemaSpec.php',
|
||||||
|
'PhabricatorPhurlURL' => 'applications/phurl/storage/PhabricatorPhurlURL.php',
|
||||||
|
'PhabricatorPhurlURLEditController' => 'applications/phurl/controller/PhabricatorPhurlURLEditController.php',
|
||||||
|
'PhabricatorPhurlURLEditor' => 'applications/phurl/editor/PhabricatorPhurlURLEditor.php',
|
||||||
|
'PhabricatorPhurlURLListController' => 'applications/phurl/controller/PhabricatorPhurlURLListController.php',
|
||||||
|
'PhabricatorPhurlURLPHIDType' => 'applications/phurl/phid/PhabricatorPhurlURLPHIDType.php',
|
||||||
|
'PhabricatorPhurlURLQuery' => 'applications/phurl/query/PhabricatorPhurlURLQuery.php',
|
||||||
|
'PhabricatorPhurlURLSearchEngine' => 'applications/phurl/query/PhabricatorPhurlURLSearchEngine.php',
|
||||||
|
'PhabricatorPhurlURLTransaction' => 'applications/phurl/storage/PhabricatorPhurlURLTransaction.php',
|
||||||
|
'PhabricatorPhurlURLTransactionComment' => 'applications/phurl/storage/PhabricatorPhurlURLTransactionComment.php',
|
||||||
|
'PhabricatorPhurlURLTransactionQuery' => 'applications/phurl/query/PhabricatorPhurlURLTransactionQuery.php',
|
||||||
|
'PhabricatorPhurlURLViewController' => 'applications/phurl/controller/PhabricatorPhurlURLViewController.php',
|
||||||
'PhabricatorPlatformSite' => 'aphront/site/PhabricatorPlatformSite.php',
|
'PhabricatorPlatformSite' => 'aphront/site/PhabricatorPlatformSite.php',
|
||||||
'PhabricatorPolicies' => 'applications/policy/constants/PhabricatorPolicies.php',
|
'PhabricatorPolicies' => 'applications/policy/constants/PhabricatorPolicies.php',
|
||||||
'PhabricatorPolicy' => 'applications/policy/storage/PhabricatorPolicy.php',
|
'PhabricatorPolicy' => 'applications/policy/storage/PhabricatorPolicy.php',
|
||||||
|
@ -6364,6 +6379,32 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPhrequentConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorPhrequentConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorPhrictionApplication' => 'PhabricatorApplication',
|
'PhabricatorPhrictionApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorPhrictionConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorPhrictionConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
|
'PhabricatorPhurlApplication' => 'PhabricatorApplication',
|
||||||
|
'PhabricatorPhurlController' => 'PhabricatorController',
|
||||||
|
'PhabricatorPhurlDAO' => 'PhabricatorLiskDAO',
|
||||||
|
'PhabricatorPhurlSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||||
|
'PhabricatorPhurlURL' => array(
|
||||||
|
'PhabricatorPhurlDAO',
|
||||||
|
'PhabricatorPolicyInterface',
|
||||||
|
'PhabricatorProjectInterface',
|
||||||
|
'PhabricatorApplicationTransactionInterface',
|
||||||
|
'PhabricatorSubscribableInterface',
|
||||||
|
'PhabricatorTokenReceiverInterface',
|
||||||
|
'PhabricatorDestructibleInterface',
|
||||||
|
'PhabricatorMentionableInterface',
|
||||||
|
'PhabricatorFlaggableInterface',
|
||||||
|
'PhabricatorSpacesInterface',
|
||||||
|
),
|
||||||
|
'PhabricatorPhurlURLEditController' => 'PhabricatorPhurlController',
|
||||||
|
'PhabricatorPhurlURLEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
|
'PhabricatorPhurlURLListController' => 'PhabricatorPhurlController',
|
||||||
|
'PhabricatorPhurlURLPHIDType' => 'PhabricatorPHIDType',
|
||||||
|
'PhabricatorPhurlURLQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorPhurlURLSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
|
'PhabricatorPhurlURLTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
|
'PhabricatorPhurlURLTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||||
|
'PhabricatorPhurlURLTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
|
'PhabricatorPhurlURLViewController' => 'PhabricatorPhurlController',
|
||||||
'PhabricatorPlatformSite' => 'PhabricatorSite',
|
'PhabricatorPlatformSite' => 'PhabricatorSite',
|
||||||
'PhabricatorPolicies' => 'PhabricatorPolicyConstants',
|
'PhabricatorPolicies' => 'PhabricatorPolicyConstants',
|
||||||
'PhabricatorPolicy' => array(
|
'PhabricatorPolicy' => array(
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlApplication extends PhabricatorApplication {
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return pht('Phurl');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShortDescription() {
|
||||||
|
return pht('URL Shortener');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFlavorText() {
|
||||||
|
return pht('Shorten your favorite URL.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBaseURI() {
|
||||||
|
return '/phurl/';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFontIcon() {
|
||||||
|
return 'fa-compress';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isPrototype() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRoutes() {
|
||||||
|
return array(
|
||||||
|
'/U(?P<id>[1-9]\d*)' => 'PhabricatorPhurlURLViewController',
|
||||||
|
'/phurl/' => array(
|
||||||
|
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
|
=> 'PhabricatorPhurlURLListController',
|
||||||
|
'url/' => array(
|
||||||
|
'create/'
|
||||||
|
=> 'PhabricatorPhurlURLEditController',
|
||||||
|
'edit/(?P<id>[1-9]\d*)/'
|
||||||
|
=> 'PhabricatorPhurlURLEditController',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorPhurlController extends PhabricatorController {
|
||||||
|
|
||||||
|
protected function buildApplicationCrumbs() {
|
||||||
|
$crumbs = parent::buildApplicationCrumbs();
|
||||||
|
$crumbs->addAction(
|
||||||
|
id(new PHUIListItemView())
|
||||||
|
->setName(pht('Shorten URL'))
|
||||||
|
->setHref($this->getApplicationURI().'url/create/')
|
||||||
|
->setIcon('fa-plus-square'));
|
||||||
|
|
||||||
|
return $crumbs;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,240 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLEditController
|
||||||
|
extends PhabricatorPhurlController {
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
$is_create = !$id;
|
||||||
|
|
||||||
|
$viewer = $request->getViewer();
|
||||||
|
$user_phid = $viewer->getPHID();
|
||||||
|
$error_name = true;
|
||||||
|
$error_long_url = true;
|
||||||
|
$validation_exception = null;
|
||||||
|
|
||||||
|
$next_workflow = $request->getStr('next');
|
||||||
|
$uri_query = $request->getStr('query');
|
||||||
|
|
||||||
|
if ($is_create) {
|
||||||
|
$url = PhabricatorPhurlURL::initializeNewPhurlURL(
|
||||||
|
$viewer);
|
||||||
|
$submit_label = pht('Create');
|
||||||
|
$page_title = pht('Shorten URL');
|
||||||
|
$subscribers = array();
|
||||||
|
$cancel_uri = $this->getApplicationURI();
|
||||||
|
} else {
|
||||||
|
$url = id(new PhabricatorPhurlURLQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($id))
|
||||||
|
->requireCapabilities(
|
||||||
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$url) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$submit_label = pht('Update');
|
||||||
|
$page_title = pht('Update URL');
|
||||||
|
|
||||||
|
$subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
||||||
|
$url->getPHID());
|
||||||
|
|
||||||
|
$cancel_uri = '/U'.$url->getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_create) {
|
||||||
|
$projects = array();
|
||||||
|
} else {
|
||||||
|
$projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||||
|
$url->getPHID(),
|
||||||
|
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
||||||
|
$projects = array_reverse($projects);
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $url->getName();
|
||||||
|
$long_url = $url->getLongURL();
|
||||||
|
$description = $url->getDescription();
|
||||||
|
$edit_policy = $url->getEditPolicy();
|
||||||
|
$view_policy = $url->getViewPolicy();
|
||||||
|
$space = $url->getSpacePHID();
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$xactions = array();
|
||||||
|
$name = $request->getStr('name');
|
||||||
|
$long_url = $request->getStr('longURL');
|
||||||
|
$projects = $request->getArr('projects');
|
||||||
|
$description = $request->getStr('description');
|
||||||
|
$subscribers = $request->getArr('subscribers');
|
||||||
|
$edit_policy = $request->getStr('editPolicy');
|
||||||
|
$view_policy = $request->getStr('viewPolicy');
|
||||||
|
$space = $request->getStr('spacePHID');
|
||||||
|
|
||||||
|
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorPhurlURLTransaction::TYPE_NAME)
|
||||||
|
->setNewValue($name);
|
||||||
|
|
||||||
|
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorPhurlURLTransaction::TYPE_URL)
|
||||||
|
->setNewValue($long_url);
|
||||||
|
|
||||||
|
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorTransactions::TYPE_SUBSCRIBERS)
|
||||||
|
->setNewValue(array('=' => array_fuse($subscribers)));
|
||||||
|
|
||||||
|
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION)
|
||||||
|
->setNewValue($description);
|
||||||
|
|
||||||
|
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
|
||||||
|
->setNewValue($view_policy);
|
||||||
|
|
||||||
|
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
|
||||||
|
->setNewValue($edit_policy);
|
||||||
|
|
||||||
|
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_SPACE)
|
||||||
|
->setNewValue($space);
|
||||||
|
|
||||||
|
$editor = id(new PhabricatorPhurlURLEditor())
|
||||||
|
->setActor($viewer)
|
||||||
|
->setContentSourceFromRequest($request)
|
||||||
|
->setContinueOnNoEffect(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
||||||
|
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||||
|
->setMetadataValue('edge:type', $proj_edge_type)
|
||||||
|
->setNewValue(array('=' => array_fuse($projects)));
|
||||||
|
|
||||||
|
$xactions = $editor->applyTransactions($url, $xactions);
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI($url->getURI());
|
||||||
|
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||||
|
$validation_exception = $ex;
|
||||||
|
$error_name = $ex->getShortMessage(
|
||||||
|
PhabricatorPhurlURLTransaction::TYPE_NAME);
|
||||||
|
$error_long_url = $ex->getShortMessage(
|
||||||
|
PhabricatorPhurlURLTransaction::TYPE_URL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$current_policies = id(new PhabricatorPolicyQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setObject($url)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$name = id(new AphrontFormTextControl())
|
||||||
|
->setLabel(pht('Name'))
|
||||||
|
->setName('name')
|
||||||
|
->setValue($name)
|
||||||
|
->setError($error_name);
|
||||||
|
|
||||||
|
$long_url = id(new AphrontFormTextControl())
|
||||||
|
->setLabel(pht('URL'))
|
||||||
|
->setName('longURL')
|
||||||
|
->setValue($long_url)
|
||||||
|
->setError($error_long_url);
|
||||||
|
|
||||||
|
$projects = id(new AphrontFormTokenizerControl())
|
||||||
|
->setLabel(pht('Projects'))
|
||||||
|
->setName('projects')
|
||||||
|
->setValue($projects)
|
||||||
|
->setUser($viewer)
|
||||||
|
->setDatasource(new PhabricatorProjectDatasource());
|
||||||
|
|
||||||
|
$description = id(new PhabricatorRemarkupControl())
|
||||||
|
->setLabel(pht('Description'))
|
||||||
|
->setName('description')
|
||||||
|
->setValue($description)
|
||||||
|
->setUser($viewer);
|
||||||
|
|
||||||
|
$view_policies = id(new AphrontFormPolicyControl())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setValue($view_policy)
|
||||||
|
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
||||||
|
->setPolicyObject($url)
|
||||||
|
->setPolicies($current_policies)
|
||||||
|
->setSpacePHID($space)
|
||||||
|
->setName('viewPolicy');
|
||||||
|
$edit_policies = id(new AphrontFormPolicyControl())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setValue($edit_policy)
|
||||||
|
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
||||||
|
->setPolicyObject($url)
|
||||||
|
->setPolicies($current_policies)
|
||||||
|
->setName('editPolicy');
|
||||||
|
|
||||||
|
$subscribers = id(new AphrontFormTokenizerControl())
|
||||||
|
->setLabel(pht('Subscribers'))
|
||||||
|
->setName('subscribers')
|
||||||
|
->setValue($subscribers)
|
||||||
|
->setUser($viewer)
|
||||||
|
->setDatasource(new PhabricatorMetaMTAMailableDatasource());
|
||||||
|
|
||||||
|
$form = id(new AphrontFormView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->appendChild($name)
|
||||||
|
->appendChild($long_url)
|
||||||
|
->appendControl($view_policies)
|
||||||
|
->appendControl($edit_policies)
|
||||||
|
->appendControl($subscribers)
|
||||||
|
->appendChild($projects)
|
||||||
|
->appendChild($description);
|
||||||
|
|
||||||
|
|
||||||
|
if ($request->isAjax()) {
|
||||||
|
return $this->newDialog()
|
||||||
|
->setTitle($page_title)
|
||||||
|
->setWidth(AphrontDialogView::WIDTH_FULL)
|
||||||
|
->appendForm($form)
|
||||||
|
->addCancelButton($cancel_uri)
|
||||||
|
->addSubmitButton($submit_label);
|
||||||
|
}
|
||||||
|
|
||||||
|
$submit = id(new AphrontFormSubmitControl())
|
||||||
|
->addCancelButton($cancel_uri)
|
||||||
|
->setValue($submit_label);
|
||||||
|
|
||||||
|
$form->appendChild($submit);
|
||||||
|
|
||||||
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText($page_title)
|
||||||
|
->setForm($form);
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
|
||||||
|
if (!$is_create) {
|
||||||
|
$crumbs->addTextCrumb($url->getMonogram(), $url->getURI());
|
||||||
|
} else {
|
||||||
|
$crumbs->addTextCrumb(pht('Create URL'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$crumbs->addTextCrumb($page_title);
|
||||||
|
|
||||||
|
$object_box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText($page_title)
|
||||||
|
->setValidationException($validation_exception)
|
||||||
|
->appendChild($form);
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
|
$object_box,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => $page_title,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLListController
|
||||||
|
extends PhabricatorPhurlController {
|
||||||
|
|
||||||
|
public function shouldAllowPublic() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$engine = new PhabricatorPhurlURLSearchEngine();
|
||||||
|
$controller = id(new PhabricatorApplicationSearchController())
|
||||||
|
->setQueryKey($request->getURIData('queryKey'))
|
||||||
|
->setSearchEngine($engine)
|
||||||
|
->setNavigation($this->buildSideNav());
|
||||||
|
return $this->delegateToController($controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSideNav() {
|
||||||
|
$user = $this->getRequest()->getUser();
|
||||||
|
|
||||||
|
$nav = new AphrontSideNavFilterView();
|
||||||
|
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||||
|
|
||||||
|
id(new PhabricatorPhurlURLSearchEngine())
|
||||||
|
->setViewer($user)
|
||||||
|
->addNavigationItems($nav->getMenu());
|
||||||
|
|
||||||
|
$nav->selectFilter(null);
|
||||||
|
|
||||||
|
return $nav;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLViewController
|
||||||
|
extends PhabricatorPhurlController {
|
||||||
|
|
||||||
|
public function shouldAllowPublic() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$viewer = $request->getViewer();
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
|
||||||
|
$timeline = null;
|
||||||
|
|
||||||
|
$url = id(new PhabricatorPhurlURLQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($id))
|
||||||
|
->executeOne();
|
||||||
|
if (!$url) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = $url->getMonogram();
|
||||||
|
$page_title = $title.' '.$url->getName();
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
$crumbs->addTextCrumb($title, $url->getURI());
|
||||||
|
|
||||||
|
$timeline = $this->buildTransactionTimeline(
|
||||||
|
$url,
|
||||||
|
new PhabricatorPhurlURLTransactionQuery());
|
||||||
|
|
||||||
|
$header = $this->buildHeaderView($url);
|
||||||
|
$actions = $this->buildActionView($url);
|
||||||
|
$properties = $this->buildPropertyView($url);
|
||||||
|
|
||||||
|
$properties->setActionList($actions);
|
||||||
|
$box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeader($header)
|
||||||
|
->addPropertyList($properties);
|
||||||
|
|
||||||
|
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
||||||
|
$add_comment_header = $is_serious
|
||||||
|
? pht('Add Comment')
|
||||||
|
: pht('More Cowbell');
|
||||||
|
$draft = PhabricatorDraft::newFromUserAndKey($viewer, $url->getPHID());
|
||||||
|
$comment_uri = $this->getApplicationURI(
|
||||||
|
'/phurl/comment/'.$url->getID().'/');
|
||||||
|
$add_comment_form = id(new PhabricatorApplicationTransactionCommentView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setObjectPHID($url->getPHID())
|
||||||
|
->setDraft($draft)
|
||||||
|
->setHeaderText($add_comment_header)
|
||||||
|
->setAction($comment_uri)
|
||||||
|
->setSubmitButtonName(pht('Add Comment'));
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
|
$box,
|
||||||
|
$timeline,
|
||||||
|
$add_comment_form,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => $page_title,
|
||||||
|
'pageObjects' => array($url->getPHID()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildHeaderView(PhabricatorPhurlURL $url) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$icon = 'fa-compress';
|
||||||
|
$color = 'green';
|
||||||
|
$status = pht('Active');
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setHeader($url->getName())
|
||||||
|
->setStatus($icon, $color, $status)
|
||||||
|
->setPolicyObject($url);
|
||||||
|
|
||||||
|
return $header;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildActionView(PhabricatorPhurlURL $url) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$id = $url->getID();
|
||||||
|
|
||||||
|
$actions = id(new PhabricatorActionListView())
|
||||||
|
->setObjectURI($url->getURI())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setObject($url);
|
||||||
|
|
||||||
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$viewer,
|
||||||
|
$url,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
|
$actions->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setName(pht('Edit'))
|
||||||
|
->setIcon('fa-pencil')
|
||||||
|
->setHref($this->getApplicationURI("url/edit/{$id}/"))
|
||||||
|
->setDisabled(!$can_edit)
|
||||||
|
->setWorkflow(!$can_edit));
|
||||||
|
|
||||||
|
return $actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildPropertyView(PhabricatorPhurlURL $url) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$properties = id(new PHUIPropertyListView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setObject($url);
|
||||||
|
|
||||||
|
$properties->addProperty(
|
||||||
|
pht('Original URL'),
|
||||||
|
$url->getLongURL());
|
||||||
|
|
||||||
|
$properties->invokeWillRenderEvent();
|
||||||
|
|
||||||
|
if (strlen($url->getDescription())) {
|
||||||
|
$description = PhabricatorMarkupEngine::renderOneObject(
|
||||||
|
id(new PhabricatorMarkupOneOff())->setContent($url->getDescription()),
|
||||||
|
'default',
|
||||||
|
$viewer);
|
||||||
|
|
||||||
|
$properties->addSectionHeader(
|
||||||
|
pht('Description'),
|
||||||
|
PHUIPropertyListView::ICON_SUMMARY);
|
||||||
|
|
||||||
|
$properties->addTextContent($description);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
207
src/applications/phurl/editor/PhabricatorPhurlURLEditor.php
Normal file
207
src/applications/phurl/editor/PhabricatorPhurlURLEditor.php
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
<?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_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_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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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_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_NAME:
|
||||||
|
$missing = $this->validateIsEmptyTextField(
|
||||||
|
$object->getName(),
|
||||||
|
$xactions);
|
||||||
|
|
||||||
|
if ($missing) {
|
||||||
|
$error = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
pht('Required'),
|
||||||
|
pht('URL name is required.'),
|
||||||
|
nonempty(last($xactions), null));
|
||||||
|
|
||||||
|
$error->setIsMissingFieldError(true);
|
||||||
|
$errors[] = $error;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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 =>
|
||||||
|
pht(
|
||||||
|
"A URL's name or path changes."),
|
||||||
|
PhabricatorPhurlURLTransaction::MAILTAG_OTHER =>
|
||||||
|
pht('Other event activity not listed above occurs.'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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->addTextSection(
|
||||||
|
pht('URL DESCRIPTION'),
|
||||||
|
$object->getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
$body->addLinkSection(
|
||||||
|
pht('URL DETAIL'),
|
||||||
|
PhabricatorEnv::getProductionURI('/U'.$object->getID()));
|
||||||
|
|
||||||
|
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
74
src/applications/phurl/phid/PhabricatorPhurlURLPHIDType.php
Normal file
74
src/applications/phurl/phid/PhabricatorPhurlURLPHIDType.php
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLPHIDType extends PhabricatorPHIDType {
|
||||||
|
|
||||||
|
const TYPECONST = 'PHRL';
|
||||||
|
|
||||||
|
public function getTypeName() {
|
||||||
|
return pht('URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPHIDTypeApplicationClass() {
|
||||||
|
return 'PhabricatorPhurlApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newObject() {
|
||||||
|
return new PhabricatorPhurlURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildQueryForObjects(
|
||||||
|
PhabricatorObjectQuery $query,
|
||||||
|
array $phids) {
|
||||||
|
|
||||||
|
return id(new PhabricatorPhurlURLQuery())
|
||||||
|
->withPHIDs($phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadHandles(
|
||||||
|
PhabricatorHandleQuery $query,
|
||||||
|
array $handles,
|
||||||
|
array $objects) {
|
||||||
|
|
||||||
|
foreach ($handles as $phid => $handle) {
|
||||||
|
$url = $objects[$phid];
|
||||||
|
|
||||||
|
$id = $url->getID();
|
||||||
|
$name = $url->getName();
|
||||||
|
$full_name = $url->getMonogram().' '.$name;
|
||||||
|
|
||||||
|
$handle
|
||||||
|
->setName($name)
|
||||||
|
->setFullName($full_name)
|
||||||
|
->setURI($url->getURI());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canLoadNamedObject($name) {
|
||||||
|
return preg_match('/^U[1-9]\d*$/i', $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadNamedObjects(
|
||||||
|
PhabricatorObjectQuery $query,
|
||||||
|
array $names) {
|
||||||
|
|
||||||
|
$id_map = array();
|
||||||
|
foreach ($names as $name) {
|
||||||
|
$id = (int)substr($name, 1);
|
||||||
|
$id_map[$id][] = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$objects = id(new PhabricatorPhurlURLQuery())
|
||||||
|
->setViewer($query->getViewer())
|
||||||
|
->withIDs(array_keys($id_map))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($objects as $id => $object) {
|
||||||
|
foreach (idx($id_map, $id, array()) as $name) {
|
||||||
|
$results[$name] = $object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
}
|
100
src/applications/phurl/query/PhabricatorPhurlURLQuery.php
Normal file
100
src/applications/phurl/query/PhabricatorPhurlURLQuery.php
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLQuery
|
||||||
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
|
private $ids;
|
||||||
|
private $phids;
|
||||||
|
private $names;
|
||||||
|
private $longURLs;
|
||||||
|
private $authorPHIDs;
|
||||||
|
|
||||||
|
public function newResultObject() {
|
||||||
|
return new PhabricatorPhurlURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withIDs(array $ids) {
|
||||||
|
$this->ids = $ids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withPHIDs(array $phids) {
|
||||||
|
$this->phids = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withNames(array $names) {
|
||||||
|
$this->names = $names;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withLongURLs(array $long_urls) {
|
||||||
|
$this->longURLs = $long_urls;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withAuthorPHIDs(array $author_phids) {
|
||||||
|
$this->authorPHIDs = $author_phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPagingValueMap($cursor, array $keys) {
|
||||||
|
$url = $this->loadCursorObject($cursor);
|
||||||
|
return array(
|
||||||
|
'id' => $url->getID(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadPage() {
|
||||||
|
return $this->loadStandardPage($this->newResultObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
|
if ($this->ids !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'url.id IN (%Ld)',
|
||||||
|
$this->ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->phids !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'url.phid IN (%Ls)',
|
||||||
|
$this->phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->authorPHIDs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'url.authorPHID IN (%Ls)',
|
||||||
|
$this->authorPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->names !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'url.name IN (%Ls)',
|
||||||
|
$this->names);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->longURLs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'url.longURL IN (%Ls)',
|
||||||
|
$this->longURLs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $where;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPrimaryTableAlias() {
|
||||||
|
return 'url';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQueryApplicationClass() {
|
||||||
|
return 'PhabricatorPhurlApplication';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLSearchEngine
|
||||||
|
extends PhabricatorApplicationSearchEngine {
|
||||||
|
|
||||||
|
public function getResultTypeDescription() {
|
||||||
|
return pht('Shortened URLs');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationClassName() {
|
||||||
|
return 'PhabricatorPhurlApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newQuery() {
|
||||||
|
return new PhabricatorPhurlURLQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function shouldShowOrderField() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildCustomSearchFields() {
|
||||||
|
return array(
|
||||||
|
id(new PhabricatorSearchDatasourceField())
|
||||||
|
->setLabel(pht('Created By'))
|
||||||
|
->setKey('authorPHIDs')
|
||||||
|
->setDatasource(new PhabricatorPeopleUserFunctionDatasource()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildQueryFromParameters(array $map) {
|
||||||
|
$query = $this->newQuery();
|
||||||
|
|
||||||
|
if ($map['authorPHIDs']) {
|
||||||
|
$query->withAuthorPHIDs($map['authorPHIDs']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getURI($path) {
|
||||||
|
return '/phurl/'.$path;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getBuiltinQueryNames() {
|
||||||
|
$names = array(
|
||||||
|
'authored' => pht('Authored'),
|
||||||
|
'all' => pht('All URLs'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSavedQueryFromBuiltin($query_key) {
|
||||||
|
$query = $this->newSavedQuery();
|
||||||
|
$query->setQueryKey($query_key);
|
||||||
|
$viewer = $this->requireViewer();
|
||||||
|
|
||||||
|
switch ($query_key) {
|
||||||
|
case 'authored':
|
||||||
|
return $query->setParameter('authorPHIDs', array($viewer->getPHID()));
|
||||||
|
case 'all':
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderResultList(
|
||||||
|
array $urls,
|
||||||
|
PhabricatorSavedQuery $query,
|
||||||
|
array $handles) {
|
||||||
|
|
||||||
|
assert_instances_of($urls, 'PhabricatorPhurlURL');
|
||||||
|
$viewer = $this->requireViewer();
|
||||||
|
$list = new PHUIObjectItemListView();
|
||||||
|
$handles = $viewer->loadHandles(mpull($urls, 'getAuthorPHID'));
|
||||||
|
|
||||||
|
foreach ($urls as $url) {
|
||||||
|
$item = id(new PHUIObjectItemView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setObject($url)
|
||||||
|
->setHeader($viewer->renderHandle($url->getPHID()));
|
||||||
|
|
||||||
|
$list->addItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = new PhabricatorApplicationSearchResultView();
|
||||||
|
$result->setObjectList($list);
|
||||||
|
$result->setNoDataString(pht('No URLs found.'));
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLTransactionQuery
|
||||||
|
extends PhabricatorApplicationTransactionQuery {
|
||||||
|
|
||||||
|
public function getTemplateApplicationTransaction() {
|
||||||
|
return new PhabricatorPhurlURLTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
src/applications/phurl/storage/PhabricatorPhurlDAO.php
Normal file
9
src/applications/phurl/storage/PhabricatorPhurlDAO.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorPhurlDAO extends PhabricatorLiskDAO {
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'phurl';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlSchemaSpec
|
||||||
|
extends PhabricatorConfigSchemaSpec {
|
||||||
|
|
||||||
|
public function buildSchemata() {
|
||||||
|
$this->buildEdgeSchemata(new PhabricatorPhurlURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
171
src/applications/phurl/storage/PhabricatorPhurlURL.php
Normal file
171
src/applications/phurl/storage/PhabricatorPhurlURL.php
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
<?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;
|
||||||
|
|
||||||
|
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',
|
||||||
|
),
|
||||||
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
|
'key_instance' => array(
|
||||||
|
'columns' => array('alias'),
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
|
'key_author' => array(
|
||||||
|
'columns' => array('authorPHID'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generatePHID() {
|
||||||
|
return PhabricatorPHID::generateNewPHID(
|
||||||
|
PhabricatorPhurlURLPHIDType::TYPECONST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMonogram() {
|
||||||
|
return 'U'.$this->getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getURI() {
|
||||||
|
$uri = '/'.$this->getMonogram();
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -( 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLTransaction
|
||||||
|
extends PhabricatorApplicationTransaction {
|
||||||
|
|
||||||
|
const TYPE_NAME = 'phurl.name';
|
||||||
|
const TYPE_URL = 'phurl.longurl';
|
||||||
|
const TYPE_DESCRIPTION = 'phurl.description';
|
||||||
|
|
||||||
|
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_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_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:
|
||||||
|
return pht(
|
||||||
|
'%s changed the destination 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 created %s.',
|
||||||
|
$this->renderHandleLink($author_phid),
|
||||||
|
$this->renderHandleLink($object_phid));
|
||||||
|
} 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_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_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:
|
||||||
|
$tags[] = self::MAILTAG_CONTENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLTransactionComment
|
||||||
|
extends PhabricatorApplicationTransactionComment {
|
||||||
|
|
||||||
|
public function getApplicationTransactionObject() {
|
||||||
|
return new PhabricatorPhurlURLTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -106,6 +106,7 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
||||||
'db.almanac' => array(),
|
'db.almanac' => array(),
|
||||||
'db.multimeter' => array(),
|
'db.multimeter' => array(),
|
||||||
'db.spaces' => array(),
|
'db.spaces' => array(),
|
||||||
|
'db.phurl' => array(),
|
||||||
'db.badges' => array(),
|
'db.badges' => array(),
|
||||||
'0000.legacy.sql' => array(
|
'0000.legacy.sql' => array(
|
||||||
'legacy' => 0,
|
'legacy' => 0,
|
||||||
|
|
Loading…
Reference in a new issue