@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Rough in most of Calendar exports

Summary:
Ref T10747. Rough flow is:

- Run a query.
- Select a new "Export Events..." action.
- This lets you define an "Export", which has a unique URL you can paste into Google Calendar or Calendar.app or whatever.

Most of this does nothing yet but here's the boilerplate.

Test Plan: Doesn't do anything yet.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10747

Differential Revision: https://secure.phabricator.com/D16675

+818 -6
+14
resources/sql/autopatches/20161005.cal.02.export.sql
··· 1 + CREATE TABLE {$NAMESPACE}_calendar.calendar_export ( 2 + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 + phid VARBINARY(64) NOT NULL, 4 + name LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}, 5 + authorPHID VARBINARY(64) NOT NULL, 6 + policyMode VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT}, 7 + queryKey VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT}, 8 + secretKey BINARY(20) NOT NULL, 9 + isDisabled BOOL NOT NULL, 10 + dateCreated INT UNSIGNED NOT NULL, 11 + dateModified INT UNSIGNED NOT NULL, 12 + KEY `key_author` (authorPHID), 13 + UNIQUE KEY `key_secret` (secretKey) 14 + ) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
+19
resources/sql/autopatches/20161005.cal.03.exportxaction.sql
··· 1 + CREATE TABLE {$NAMESPACE}_calendar.calendar_exporttransaction ( 2 + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 + phid VARBINARY(64) NOT NULL, 4 + authorPHID VARBINARY(64) NOT NULL, 5 + objectPHID VARBINARY(64) NOT NULL, 6 + viewPolicy VARBINARY(64) NOT NULL, 7 + editPolicy VARBINARY(64) NOT NULL, 8 + commentPHID VARBINARY(64) DEFAULT NULL, 9 + commentVersion INT UNSIGNED NOT NULL, 10 + transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL, 11 + oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 12 + newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 13 + contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 14 + metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 15 + dateCreated INT UNSIGNED NOT NULL, 16 + dateModified INT UNSIGNED NOT NULL, 17 + UNIQUE KEY `key_phid` (`phid`), 18 + KEY `key_object` (`objectPHID`) 19 + ) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
+33
src/__phutil_library_map__.php
··· 2075 2075 'PhabricatorCalendarEventTransactionType' => 'applications/calendar/xaction/PhabricatorCalendarEventTransactionType.php', 2076 2076 'PhabricatorCalendarEventUntilDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventUntilDateTransaction.php', 2077 2077 'PhabricatorCalendarEventViewController' => 'applications/calendar/controller/PhabricatorCalendarEventViewController.php', 2078 + 'PhabricatorCalendarExport' => 'applications/calendar/storage/PhabricatorCalendarExport.php', 2079 + 'PhabricatorCalendarExportDisableTransaction' => 'applications/calendar/xaction/PhabricatorCalendarExportDisableTransaction.php', 2080 + 'PhabricatorCalendarExportEditController' => 'applications/calendar/controller/PhabricatorCalendarExportEditController.php', 2081 + 'PhabricatorCalendarExportEditEngine' => 'applications/calendar/editor/PhabricatorCalendarExportEditEngine.php', 2082 + 'PhabricatorCalendarExportEditor' => 'applications/calendar/editor/PhabricatorCalendarExportEditor.php', 2083 + 'PhabricatorCalendarExportListController' => 'applications/calendar/controller/PhabricatorCalendarExportListController.php', 2084 + 'PhabricatorCalendarExportModeTransaction' => 'applications/calendar/xaction/PhabricatorCalendarExportModeTransaction.php', 2085 + 'PhabricatorCalendarExportNameTransaction' => 'applications/calendar/xaction/PhabricatorCalendarExportNameTransaction.php', 2086 + 'PhabricatorCalendarExportPHIDType' => 'applications/calendar/phid/PhabricatorCalendarExportPHIDType.php', 2087 + 'PhabricatorCalendarExportQuery' => 'applications/calendar/query/PhabricatorCalendarExportQuery.php', 2088 + 'PhabricatorCalendarExportQueryKeyTransaction' => 'applications/calendar/xaction/PhabricatorCalendarExportQueryKeyTransaction.php', 2089 + 'PhabricatorCalendarExportSearchEngine' => 'applications/calendar/query/PhabricatorCalendarExportSearchEngine.php', 2090 + 'PhabricatorCalendarExportTransaction' => 'applications/calendar/storage/PhabricatorCalendarExportTransaction.php', 2091 + 'PhabricatorCalendarExportTransactionType' => 'applications/calendar/xaction/PhabricatorCalendarExportTransactionType.php', 2078 2092 'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php', 2079 2093 'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php', 2080 2094 'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php', ··· 6825 6839 'PhabricatorCalendarEventTransactionType' => 'PhabricatorModularTransactionType', 6826 6840 'PhabricatorCalendarEventUntilDateTransaction' => 'PhabricatorCalendarEventDateTransaction', 6827 6841 'PhabricatorCalendarEventViewController' => 'PhabricatorCalendarController', 6842 + 'PhabricatorCalendarExport' => array( 6843 + 'PhabricatorCalendarDAO', 6844 + 'PhabricatorPolicyInterface', 6845 + 'PhabricatorApplicationTransactionInterface', 6846 + 'PhabricatorDestructibleInterface', 6847 + ), 6848 + 'PhabricatorCalendarExportDisableTransaction' => 'PhabricatorCalendarExportTransactionType', 6849 + 'PhabricatorCalendarExportEditController' => 'PhabricatorCalendarController', 6850 + 'PhabricatorCalendarExportEditEngine' => 'PhabricatorEditEngine', 6851 + 'PhabricatorCalendarExportEditor' => 'PhabricatorApplicationTransactionEditor', 6852 + 'PhabricatorCalendarExportListController' => 'PhabricatorCalendarController', 6853 + 'PhabricatorCalendarExportModeTransaction' => 'PhabricatorCalendarExportTransactionType', 6854 + 'PhabricatorCalendarExportNameTransaction' => 'PhabricatorCalendarExportTransactionType', 6855 + 'PhabricatorCalendarExportPHIDType' => 'PhabricatorPHIDType', 6856 + 'PhabricatorCalendarExportQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 6857 + 'PhabricatorCalendarExportQueryKeyTransaction' => 'PhabricatorCalendarExportTransactionType', 6858 + 'PhabricatorCalendarExportSearchEngine' => 'PhabricatorApplicationSearchEngine', 6859 + 'PhabricatorCalendarExportTransaction' => 'PhabricatorModularTransaction', 6860 + 'PhabricatorCalendarExportTransactionType' => 'PhabricatorModularTransactionType', 6828 6861 'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO', 6829 6862 'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase', 6830 6863 'PhabricatorCalendarIconSet' => 'PhabricatorIconSet',
+10
src/applications/calendar/application/PhabricatorCalendarApplication.php
··· 62 62 'export/(?P<id>[1-9]\d*)/(?P<filename>[^/]*)' 63 63 => 'PhabricatorCalendarEventExportController', 64 64 ), 65 + 'export/' => array( 66 + $this->getQueryRoutePattern() 67 + => 'PhabricatorCalendarExportListController', 68 + $this->getEditRoutePattern('edit/') 69 + => 'PhabricatorCalendarExportEditController', 70 + '(?P<id>[1-9]\d*)/' 71 + => 'PhabricatorCalendarExportViewController', 72 + 'ics/(?P<secretKey>[^/]+)/(?P<filename>[^/]*)' 73 + => 'PhabricatorCalendarExportICSController', 74 + ), 65 75 ), 66 76 ); 67 77 }
+12
src/applications/calendar/controller/PhabricatorCalendarExportEditController.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportEditController 4 + extends PhabricatorCalendarController { 5 + 6 + public function handleRequest(AphrontRequest $request) { 7 + return id(new PhabricatorCalendarExportEditEngine()) 8 + ->setController($this) 9 + ->buildResponse(); 10 + } 11 + 12 + }
+27
src/applications/calendar/controller/PhabricatorCalendarExportListController.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportListController 4 + extends PhabricatorCalendarController { 5 + 6 + public function handleRequest(AphrontRequest $request) { 7 + return id(new PhabricatorCalendarExportSearchEngine()) 8 + ->setController($this) 9 + ->buildResponse(); 10 + } 11 + 12 + protected function buildApplicationCrumbs() { 13 + $crumbs = parent::buildApplicationCrumbs(); 14 + 15 + $doc_name = 'Calendar User Guide: Exporting Events'; 16 + $doc_href = PhabricatorEnv::getDoclink($doc_name); 17 + 18 + $crumbs->addAction( 19 + id(new PHUIListItemView()) 20 + ->setName(pht('Guide: Exporting Events')) 21 + ->setIcon('fa-book') 22 + ->setHref($doc_href)); 23 + 24 + return $crumbs; 25 + } 26 + 27 + }
+96
src/applications/calendar/editor/PhabricatorCalendarExportEditEngine.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportEditEngine 4 + extends PhabricatorEditEngine { 5 + 6 + const ENGINECONST = 'calendar.export'; 7 + 8 + public function getEngineName() { 9 + return pht('Calendar Exports'); 10 + } 11 + 12 + public function isEngineConfigurable() { 13 + return false; 14 + } 15 + 16 + public function getSummaryHeader() { 17 + return pht('Configure Calendar Export Forms'); 18 + } 19 + 20 + public function getSummaryText() { 21 + return pht('Configure how users create and edit exports.'); 22 + } 23 + 24 + public function getEngineApplicationClass() { 25 + return 'PhabricatorCalendarApplication'; 26 + } 27 + 28 + protected function newEditableObject() { 29 + return PhabricatorCalendarExport::initializeNewCalendarExport( 30 + $this->getViewer()); 31 + } 32 + 33 + protected function newObjectQuery() { 34 + return new PhabricatorCalendarExportQuery(); 35 + } 36 + 37 + protected function getObjectCreateTitleText($object) { 38 + return pht('Create New Export'); 39 + } 40 + 41 + protected function getObjectEditTitleText($object) { 42 + return pht('Edit Export: %s', $object->getName()); 43 + } 44 + 45 + protected function getObjectEditShortText($object) { 46 + return $object->getMonogram(); 47 + } 48 + 49 + protected function getObjectCreateShortText() { 50 + return pht('Create Export'); 51 + } 52 + 53 + protected function getObjectName() { 54 + return pht('Export'); 55 + } 56 + 57 + protected function getObjectViewURI($object) { 58 + return $object->getURI(); 59 + } 60 + 61 + protected function getEditorURI() { 62 + return $this->getApplication()->getApplicationURI('export/edit/'); 63 + } 64 + 65 + protected function buildCustomEditFields($object) { 66 + $viewer = $this->getViewer(); 67 + 68 + $fields = array( 69 + id(new PhabricatorTextEditField()) 70 + ->setKey('name') 71 + ->setLabel(pht('Name')) 72 + ->setDescription(pht('Name of the export.')) 73 + ->setIsRequired(true) 74 + ->setTransactionType( 75 + PhabricatorCalendarExportNameTransaction::TRANSACTIONTYPE) 76 + ->setConduitDescription(pht('Rename the export.')) 77 + ->setConduitTypeDescription(pht('New export name.')) 78 + ->setValue($object->getName()), 79 + id(new PhabricatorBoolEditField()) 80 + ->setKey('disabled') 81 + ->setOptions(pht('Active'), pht('Disabled')) 82 + ->setLabel(pht('Disabled')) 83 + ->setDescription(pht('Disable the export.')) 84 + ->setTransactionType( 85 + PhabricatorCalendarExportDisableTransaction::TRANSACTIONTYPE) 86 + ->setIsConduitOnly(true) 87 + ->setConduitDescription(pht('Disable or restore the export.')) 88 + ->setConduitTypeDescription(pht('True to cancel the export.')) 89 + ->setValue($object->getIsDisabled()), 90 + ); 91 + 92 + return $fields; 93 + } 94 + 95 + 96 + }
+14
src/applications/calendar/editor/PhabricatorCalendarExportEditor.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportEditor 4 + extends PhabricatorApplicationTransactionEditor { 5 + 6 + public function getEditorApplicationClass() { 7 + return 'PhabricatorCalendarApplication'; 8 + } 9 + 10 + public function getEditorObjectsDescription() { 11 + return pht('Calendar Exports'); 12 + } 13 + 14 + }
+50
src/applications/calendar/phid/PhabricatorCalendarExportPHIDType.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportPHIDType extends PhabricatorPHIDType { 4 + 5 + const TYPECONST = 'CEXP'; 6 + 7 + public function getTypeName() { 8 + return pht('Calendar Export'); 9 + } 10 + 11 + public function newObject() { 12 + return new PhabricatorCalendarExport(); 13 + } 14 + 15 + public function getPHIDTypeApplicationClass() { 16 + return 'PhabricatorCalendarApplication'; 17 + } 18 + 19 + protected function buildQueryForObjects( 20 + PhabricatorObjectQuery $query, 21 + array $phids) { 22 + 23 + return id(new PhabricatorCalendarExportQuery()) 24 + ->withPHIDs($phids); 25 + } 26 + 27 + public function loadHandles( 28 + PhabricatorHandleQuery $query, 29 + array $handles, 30 + array $objects) { 31 + 32 + foreach ($handles as $phid => $handle) { 33 + $export = $objects[$phid]; 34 + 35 + $id = $export->getID(); 36 + $name = $export->getName(); 37 + $uri = $export->getURI(); 38 + 39 + $handle 40 + ->setName($name) 41 + ->setFullName(pht('Calendar Export %s: %s', $id, $name)) 42 + ->setURI($uri); 43 + 44 + if ($export->getIsDisabled()) { 45 + $handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED); 46 + } 47 + } 48 + } 49 + 50 + }
+81
src/applications/calendar/query/PhabricatorCalendarExportQuery.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportQuery 4 + extends PhabricatorCursorPagedPolicyAwareQuery { 5 + 6 + private $ids; 7 + private $phids; 8 + private $authorPHIDs; 9 + private $isDisabled; 10 + 11 + public function withIDs(array $ids) { 12 + $this->ids = $ids; 13 + return $this; 14 + } 15 + 16 + public function withPHIDs(array $phids) { 17 + $this->phids = $phids; 18 + return $this; 19 + } 20 + 21 + public function withAuthorPHIDs(array $phids) { 22 + $this->authorPHIDs = $phids; 23 + return $this; 24 + } 25 + 26 + public function withIsDisabled($is_disabled) { 27 + $this->isDisabled = $is_disabled; 28 + return $this; 29 + } 30 + 31 + public function newResultObject() { 32 + return new PhabricatorCalendarExport(); 33 + } 34 + 35 + protected function loadPage() { 36 + return $this->loadStandardPage($this->newResultObject()); 37 + } 38 + 39 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 40 + $where = parent::buildWhereClauseParts($conn); 41 + 42 + if ($this->ids !== null) { 43 + $where[] = qsprintf( 44 + $conn, 45 + 'export.id IN (%Ld)', 46 + $this->ids); 47 + } 48 + 49 + if ($this->phids !== null) { 50 + $where[] = qsprintf( 51 + $conn, 52 + 'export.phid IN (%Ls)', 53 + $this->phids); 54 + } 55 + 56 + if ($this->authorPHIDs !== null) { 57 + $where[] = qsprintf( 58 + $conn, 59 + 'export.authorPHID IN (%Ls)', 60 + $this->authorPHIDs); 61 + } 62 + 63 + if ($this->isDisabled !== null) { 64 + $where[] = qsprintf( 65 + $conn, 66 + 'export.isDisabled = %d', 67 + (int)$this->isDisabled); 68 + } 69 + 70 + return $where; 71 + } 72 + 73 + protected function getPrimaryTableAlias() { 74 + return 'export'; 75 + } 76 + 77 + public function getQueryApplicationClass() { 78 + return 'PhabricatorCalendarApplication'; 79 + } 80 + 81 + }
+109
src/applications/calendar/query/PhabricatorCalendarExportSearchEngine.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportSearchEngine 4 + extends PhabricatorApplicationSearchEngine { 5 + 6 + public function getResultTypeDescription() { 7 + return pht('Calendar Exports'); 8 + } 9 + 10 + public function getApplicationClassName() { 11 + return 'PhabricatorCalendarApplication'; 12 + } 13 + 14 + public function newQuery() { 15 + $viewer = $this->requireViewer(); 16 + 17 + return id(new PhabricatorCalendarExportQuery()) 18 + ->withAuthorPHIDs(array($viewer->getPHID())); 19 + } 20 + 21 + protected function buildCustomSearchFields() { 22 + return array(); 23 + } 24 + 25 + protected function buildQueryFromParameters(array $map) { 26 + $query = $this->newQuery(); 27 + 28 + return $query; 29 + } 30 + 31 + protected function getURI($path) { 32 + return '/calendar/export/'.$path; 33 + } 34 + 35 + protected function getBuiltinQueryNames() { 36 + $names = array( 37 + 'all' => pht('All Exports'), 38 + ); 39 + 40 + return $names; 41 + } 42 + 43 + public function buildSavedQueryFromBuiltin($query_key) { 44 + $query = $this->newSavedQuery(); 45 + $query->setQueryKey($query_key); 46 + 47 + switch ($query_key) { 48 + case 'all': 49 + return $query; 50 + } 51 + 52 + return parent::buildSavedQueryFromBuiltin($query_key); 53 + } 54 + 55 + protected function renderResultList( 56 + array $exports, 57 + PhabricatorSavedQuery $query, 58 + array $handles) { 59 + 60 + assert_instances_of($exports, 'PhabricatorCalendarExport'); 61 + $viewer = $this->requireViewer(); 62 + 63 + $list = new PHUIObjectItemListView(); 64 + foreach ($exports as $export) { 65 + $item = id(new PHUIObjectItemView()) 66 + ->setViewer($viewer) 67 + ->setHeader($export->getName()) 68 + ->setHref($export->getURI()); 69 + 70 + if ($export->getIsDisabled()) { 71 + $item->setDisabled(true); 72 + } 73 + 74 + $list->addItem($item); 75 + } 76 + 77 + $result = new PhabricatorApplicationSearchResultView(); 78 + $result->setObjectList($list); 79 + $result->setNoDataString(pht('No exports found.')); 80 + 81 + return $result; 82 + } 83 + 84 + protected function getNewUserBody() { 85 + $doc_name = 'Calendar User Guide: Exporting Events'; 86 + $doc_href = PhabricatorEnv::getDoclink($doc_name); 87 + 88 + $create_button = id(new PHUIButtonView()) 89 + ->setTag('a') 90 + ->setIcon('fa-book white') 91 + ->setText($doc_name) 92 + ->setHref($doc_href) 93 + ->setColor(PHUIButtonView::GREEN); 94 + 95 + $icon = $this->getApplication()->getIcon(); 96 + $app_name = $this->getApplication()->getName(); 97 + $view = id(new PHUIBigInfoView()) 98 + ->setIcon('fa-download') 99 + ->setTitle(pht('No Exports Configured')) 100 + ->setDescription( 101 + pht( 102 + 'You have not set up any events for export from Calendar yet. '. 103 + 'See the documentation for instructions on how to get started.')) 104 + ->addAction($create_button); 105 + 106 + return $view; 107 + } 108 + 109 + }
+144
src/applications/calendar/storage/PhabricatorCalendarExport.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExport extends PhabricatorCalendarDAO 4 + implements 5 + PhabricatorPolicyInterface, 6 + PhabricatorApplicationTransactionInterface, 7 + PhabricatorDestructibleInterface { 8 + 9 + protected $name; 10 + protected $authorPHID; 11 + protected $policyMode; 12 + protected $queryKey; 13 + protected $secretKey; 14 + protected $isDisabled = 0; 15 + 16 + const MODE_PUBLIC = 'public'; 17 + const MODE_PRIVATE = 'private'; 18 + 19 + public static function initializeNewCalendarExport(PhabricatorUser $actor) { 20 + return id(new self()) 21 + ->setAuthorPHID($actor->getPHID()) 22 + ->setPolicyMode(self::MODE_PRIVATE) 23 + ->setIsDisabled(0); 24 + } 25 + 26 + protected function getConfiguration() { 27 + return array( 28 + self::CONFIG_AUX_PHID => true, 29 + self::CONFIG_COLUMN_SCHEMA => array( 30 + 'name' => 'text', 31 + 'policyMode' => 'text64', 32 + 'queryKey' => 'text64', 33 + 'secretKey' => 'bytes20', 34 + 'isDisabled' => 'bool', 35 + ), 36 + self::CONFIG_KEY_SCHEMA => array( 37 + 'key_author' => array( 38 + 'columns' => array('authorPHID'), 39 + ), 40 + 'key_secret' => array( 41 + 'columns' => array('secretKey'), 42 + 'unique' => true, 43 + ), 44 + ), 45 + ) + parent::getConfiguration(); 46 + } 47 + 48 + public function getPHIDType() { 49 + return PhabricatorCalendarExportPHIDType::TYPECONST; 50 + } 51 + 52 + public function save() { 53 + if (!$this->getSecretKey()) { 54 + $this->setSecretKey(Filesystem::readRandomCharacters(20)); 55 + } 56 + 57 + return parent::save(); 58 + } 59 + 60 + public function getURI() { 61 + $id = $this->getID(); 62 + return "/calendar/export/{$id}/"; 63 + } 64 + 65 + private static function getPolicyModeMap() { 66 + return array( 67 + self::MODE_PUBLIC => array( 68 + 'name' => pht('Public'), 69 + ), 70 + self::MODE_PRIVATE => array( 71 + 'name' => pht('Private'), 72 + ), 73 + ); 74 + } 75 + 76 + private static function getPolicyModeSpec($const) { 77 + return idx(self::getPolicyModeMap(), $const, array()); 78 + } 79 + 80 + public static function getPolicyModeName($const) { 81 + $map = self::getPolicyModeSpec($const); 82 + return idx($map, 'name', $const); 83 + } 84 + 85 + public static function getPolicyModes() { 86 + return array_keys(self::getPolicyModeMap()); 87 + } 88 + 89 + 90 + /* -( PhabricatorPolicyInterface )----------------------------------------- */ 91 + 92 + 93 + public function getCapabilities() { 94 + return array( 95 + PhabricatorPolicyCapability::CAN_VIEW, 96 + PhabricatorPolicyCapability::CAN_EDIT, 97 + ); 98 + } 99 + 100 + public function getPolicy($capability) { 101 + return $this->getAuthorPHID(); 102 + } 103 + 104 + public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 105 + return false; 106 + } 107 + 108 + public function describeAutomaticCapability($capability) { 109 + return null; 110 + } 111 + 112 + 113 + /* -( PhabricatorApplicationTransactionInterface )------------------------- */ 114 + 115 + 116 + public function getApplicationTransactionEditor() { 117 + return new PhabricatorCalendarExportEditor(); 118 + } 119 + 120 + public function getApplicationTransactionObject() { 121 + return $this; 122 + } 123 + 124 + public function getApplicationTransactionTemplate() { 125 + return new PhabricatorCalendarExportTransaction(); 126 + } 127 + 128 + public function willRenderTimeline( 129 + PhabricatorApplicationTransactionView $timeline, 130 + AphrontRequest $request) { 131 + 132 + return $timeline; 133 + } 134 + 135 + 136 + /* -( PhabricatorDestructibleInterface )----------------------------------- */ 137 + 138 + 139 + public function destroyObjectPermanently( 140 + PhabricatorDestructionEngine $engine) { 141 + $this->delete(); 142 + } 143 + 144 + }
+18
src/applications/calendar/storage/PhabricatorCalendarExportTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportTransaction 4 + extends PhabricatorModularTransaction { 5 + 6 + public function getApplicationName() { 7 + return 'calendar'; 8 + } 9 + 10 + public function getApplicationTransactionType() { 11 + return PhabricatorCalendarExportPHIDType::TYPECONST; 12 + } 13 + 14 + public function getBaseTransactionClass() { 15 + return 'PhabricatorCalendarExportTransactionType'; 16 + } 17 + 18 + }
+28
src/applications/calendar/xaction/PhabricatorCalendarExportDisableTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportDisableTransaction 4 + extends PhabricatorCalendarExportTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'calendar.export.disable'; 7 + 8 + public function generateOldValue($object) { 9 + return (int)$object->getIsDisabled(); 10 + } 11 + 12 + public function applyInternalEffects($object, $value) { 13 + $object->setIsDisabled((int)$value); 14 + } 15 + 16 + public function getTitle() { 17 + if ($this->getNewValue()) { 18 + return pht( 19 + '%s disabled this export.', 20 + $this->renderAuthor()); 21 + } else { 22 + return pht( 23 + '%s enabled this export.', 24 + $this->renderAuthor()); 25 + } 26 + } 27 + 28 + }
+54
src/applications/calendar/xaction/PhabricatorCalendarExportModeTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportModeTransaction 4 + extends PhabricatorCalendarExportTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'calendar.export.mode'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getPolicyMode(); 10 + } 11 + 12 + public function applyInternalEffects($object, $value) { 13 + $object->setPolicyMode($value); 14 + } 15 + 16 + public function getTitle() { 17 + $old_value = $this->getOldValue(); 18 + $new_value = $this->getNewValue(); 19 + 20 + $old_name = PhabricatorCalendarExport::getPolicyModeName($old_value); 21 + $new_name = PhabricatorCalendarExport::getPolicyModeName($new_value); 22 + 23 + return pht( 24 + '%s changed the policy mode for this export from %s to %s.', 25 + $this->renderAuthor(), 26 + $this->renderValue($old_name), 27 + $this->renderValue($new_name)); 28 + } 29 + 30 + public function validateTransactions($object, array $xactions) { 31 + $errors = array(); 32 + 33 + $valid = PhabricatorCalendarExport::getPolicyModes(); 34 + $valid = array_fuse($valid); 35 + 36 + foreach ($xactions as $xaction) { 37 + $value = $xaction->getNewValue(); 38 + 39 + if (isset($valid[$value])) { 40 + continue; 41 + } 42 + 43 + $errors[] = $this->newInvalidError( 44 + pht( 45 + 'Mode "%s" is not a valid policy mode. Valid modes are: %s.', 46 + $value, 47 + implode(', ', $valid)), 48 + $xaction); 49 + } 50 + 51 + return $errors; 52 + } 53 + 54 + }
+35
src/applications/calendar/xaction/PhabricatorCalendarExportNameTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportNameTransaction 4 + extends PhabricatorCalendarExportTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'calendar.export.name'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getName(); 10 + } 11 + 12 + public function applyInternalEffects($object, $value) { 13 + $object->setName($value); 14 + } 15 + 16 + public function getTitle() { 17 + return pht( 18 + '%s renamed this export from %s to %s.', 19 + $this->renderAuthor(), 20 + $this->renderOldValue(), 21 + $this->renderNewValue()); 22 + } 23 + 24 + public function validateTransactions($object, array $xactions) { 25 + $errors = array(); 26 + 27 + if ($this->isEmptyTextTransaction($object->getName(), $xactions)) { 28 + $errors[] = $this->newRequiredError( 29 + pht('Calendar exports must have a name.')); 30 + } 31 + 32 + return $errors; 33 + } 34 + 35 + }
+51
src/applications/calendar/xaction/PhabricatorCalendarExportQueryKeyTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarExportQueryKeyTransaction 4 + extends PhabricatorCalendarExportTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'calendar.export.querykey'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getQueryKey(); 10 + } 11 + 12 + public function applyInternalEffects($object, $value) { 13 + $object->setQueryKey($value); 14 + } 15 + 16 + public function getTitle() { 17 + return pht( 18 + '%s changed the query for this export.', 19 + $this->renderAuthor()); 20 + } 21 + 22 + public function validateTransactions($object, array $xactions) { 23 + $errors = array(); 24 + 25 + foreach ($xactions as $xaction) { 26 + $value = $xaction->getNewValue(); 27 + 28 + $query = id(new PhabricatorSavedQueryQuery()) 29 + ->withEngineClassNames(array('PhabricatorCalendarEventSearchEngine')) 30 + ->withQueryKeys(array($value)) 31 + ->executeOne(); 32 + if ($query) { 33 + continue; 34 + } 35 + 36 + $errors[] = $this->newInvalidError( 37 + pht( 38 + 'Query key "%s" does not identify a valid event query.', 39 + $value), 40 + $xaction); 41 + } 42 + 43 + if ($this->isEmptyTextTransaction($object->getQueryKey(), $xactions)) { 44 + $errors[] = $this->newRequiredError( 45 + pht('Calendar exports must have a query key.')); 46 + } 47 + 48 + return $errors; 49 + } 50 + 51 + }
+4
src/applications/calendar/xaction/PhabricatorCalendarExportTransactionType.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorCalendarExportTransactionType 4 + extends PhabricatorModularTransactionType {}
+1 -1
src/applications/maniphest/query/ManiphestTaskSearchEngine.php
··· 421 421 'you need to get done. Tasks assigned to you will appear here.')) 422 422 ->addAction($create_button); 423 423 424 - return $view; 424 + return $view; 425 425 } 426 426 427 427 }
+12
src/docs/user/userguide/calendar_exports.diviner
··· 1 + @title Calendar User Guide: Exporting Events 2 + @group userguide 3 + 4 + Exporting events to other calendars. 5 + 6 + Overview 7 + ======== 8 + 9 + IMPORTANT: Calendar is a prototype application. See 10 + @{article:User Guide: Prototype Applications}. 11 + 12 + Coming soon!
+6 -5
src/infrastructure/storage/lisk/LiskDAO.php
··· 1339 1339 * @task hook 1340 1340 */ 1341 1341 public function generatePHID() { 1342 - throw new Exception( 1343 - pht( 1344 - 'To use %s, you need to overload %s to perform PHID generation.', 1345 - 'CONFIG_AUX_PHID', 1346 - 'generatePHID()')); 1342 + $type = $this->getPHIDType(); 1343 + return PhabricatorPHID::generateNewPHID($type); 1344 + } 1345 + 1346 + public function getPHIDType() { 1347 + throw new PhutilMethodNotImplementedException(); 1347 1348 } 1348 1349 1349 1350