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:
		
							
								
								
									
										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',
 | 
			
		||||
    'PhabricatorPhrictionApplication' => 'applications/phriction/application/PhabricatorPhrictionApplication.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',
 | 
			
		||||
    'PhabricatorPolicies' => 'applications/policy/constants/PhabricatorPolicies.php',
 | 
			
		||||
    'PhabricatorPolicy' => 'applications/policy/storage/PhabricatorPolicy.php',
 | 
			
		||||
@@ -6364,6 +6379,32 @@ phutil_register_library_map(array(
 | 
			
		||||
    'PhabricatorPhrequentConfigOptions' => 'PhabricatorApplicationConfigOptions',
 | 
			
		||||
    'PhabricatorPhrictionApplication' => 'PhabricatorApplication',
 | 
			
		||||
    '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',
 | 
			
		||||
    'PhabricatorPolicies' => 'PhabricatorPolicyConstants',
 | 
			
		||||
    '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.multimeter' => array(),
 | 
			
		||||
      'db.spaces' => array(),
 | 
			
		||||
      'db.phurl' => array(),
 | 
			
		||||
      'db.badges' => array(),
 | 
			
		||||
      '0000.legacy.sql' => array(
 | 
			
		||||
        'legacy' => 0,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user