Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13994937
D16675.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
30 KB
Referenced Files
None
Subscribers
None
D16675.diff
View Options
diff --git a/resources/sql/autopatches/20161005.cal.02.export.sql b/resources/sql/autopatches/20161005.cal.02.export.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20161005.cal.02.export.sql
@@ -0,0 +1,14 @@
+CREATE TABLE {$NAMESPACE}_calendar.calendar_export (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ name LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
+ authorPHID VARBINARY(64) NOT NULL,
+ policyMode VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT},
+ queryKey VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT},
+ secretKey BINARY(20) NOT NULL,
+ isDisabled BOOL NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ KEY `key_author` (authorPHID),
+ UNIQUE KEY `key_secret` (secretKey)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20161005.cal.03.exportxaction.sql b/resources/sql/autopatches/20161005.cal.03.exportxaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20161005.cal.03.exportxaction.sql
@@ -0,0 +1,19 @@
+CREATE TABLE {$NAMESPACE}_calendar.calendar_exporttransaction (
+ 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};
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2075,6 +2075,20 @@
'PhabricatorCalendarEventTransactionType' => 'applications/calendar/xaction/PhabricatorCalendarEventTransactionType.php',
'PhabricatorCalendarEventUntilDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventUntilDateTransaction.php',
'PhabricatorCalendarEventViewController' => 'applications/calendar/controller/PhabricatorCalendarEventViewController.php',
+ 'PhabricatorCalendarExport' => 'applications/calendar/storage/PhabricatorCalendarExport.php',
+ 'PhabricatorCalendarExportDisableTransaction' => 'applications/calendar/xaction/PhabricatorCalendarExportDisableTransaction.php',
+ 'PhabricatorCalendarExportEditController' => 'applications/calendar/controller/PhabricatorCalendarExportEditController.php',
+ 'PhabricatorCalendarExportEditEngine' => 'applications/calendar/editor/PhabricatorCalendarExportEditEngine.php',
+ 'PhabricatorCalendarExportEditor' => 'applications/calendar/editor/PhabricatorCalendarExportEditor.php',
+ 'PhabricatorCalendarExportListController' => 'applications/calendar/controller/PhabricatorCalendarExportListController.php',
+ 'PhabricatorCalendarExportModeTransaction' => 'applications/calendar/xaction/PhabricatorCalendarExportModeTransaction.php',
+ 'PhabricatorCalendarExportNameTransaction' => 'applications/calendar/xaction/PhabricatorCalendarExportNameTransaction.php',
+ 'PhabricatorCalendarExportPHIDType' => 'applications/calendar/phid/PhabricatorCalendarExportPHIDType.php',
+ 'PhabricatorCalendarExportQuery' => 'applications/calendar/query/PhabricatorCalendarExportQuery.php',
+ 'PhabricatorCalendarExportQueryKeyTransaction' => 'applications/calendar/xaction/PhabricatorCalendarExportQueryKeyTransaction.php',
+ 'PhabricatorCalendarExportSearchEngine' => 'applications/calendar/query/PhabricatorCalendarExportSearchEngine.php',
+ 'PhabricatorCalendarExportTransaction' => 'applications/calendar/storage/PhabricatorCalendarExportTransaction.php',
+ 'PhabricatorCalendarExportTransactionType' => 'applications/calendar/xaction/PhabricatorCalendarExportTransactionType.php',
'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php',
@@ -6825,6 +6839,25 @@
'PhabricatorCalendarEventTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorCalendarEventUntilDateTransaction' => 'PhabricatorCalendarEventDateTransaction',
'PhabricatorCalendarEventViewController' => 'PhabricatorCalendarController',
+ 'PhabricatorCalendarExport' => array(
+ 'PhabricatorCalendarDAO',
+ 'PhabricatorPolicyInterface',
+ 'PhabricatorApplicationTransactionInterface',
+ 'PhabricatorDestructibleInterface',
+ ),
+ 'PhabricatorCalendarExportDisableTransaction' => 'PhabricatorCalendarExportTransactionType',
+ 'PhabricatorCalendarExportEditController' => 'PhabricatorCalendarController',
+ 'PhabricatorCalendarExportEditEngine' => 'PhabricatorEditEngine',
+ 'PhabricatorCalendarExportEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'PhabricatorCalendarExportListController' => 'PhabricatorCalendarController',
+ 'PhabricatorCalendarExportModeTransaction' => 'PhabricatorCalendarExportTransactionType',
+ 'PhabricatorCalendarExportNameTransaction' => 'PhabricatorCalendarExportTransactionType',
+ 'PhabricatorCalendarExportPHIDType' => 'PhabricatorPHIDType',
+ 'PhabricatorCalendarExportQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhabricatorCalendarExportQueryKeyTransaction' => 'PhabricatorCalendarExportTransactionType',
+ 'PhabricatorCalendarExportSearchEngine' => 'PhabricatorApplicationSearchEngine',
+ 'PhabricatorCalendarExportTransaction' => 'PhabricatorModularTransaction',
+ 'PhabricatorCalendarExportTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
'PhabricatorCalendarIconSet' => 'PhabricatorIconSet',
diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php
--- a/src/applications/calendar/application/PhabricatorCalendarApplication.php
+++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php
@@ -62,6 +62,16 @@
'export/(?P<id>[1-9]\d*)/(?P<filename>[^/]*)'
=> 'PhabricatorCalendarEventExportController',
),
+ 'export/' => array(
+ $this->getQueryRoutePattern()
+ => 'PhabricatorCalendarExportListController',
+ $this->getEditRoutePattern('edit/')
+ => 'PhabricatorCalendarExportEditController',
+ '(?P<id>[1-9]\d*)/'
+ => 'PhabricatorCalendarExportViewController',
+ 'ics/(?P<secretKey>[^/]+)/(?P<filename>[^/]*)'
+ => 'PhabricatorCalendarExportICSController',
+ ),
),
);
}
diff --git a/src/applications/calendar/controller/PhabricatorCalendarExportEditController.php b/src/applications/calendar/controller/PhabricatorCalendarExportEditController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/controller/PhabricatorCalendarExportEditController.php
@@ -0,0 +1,12 @@
+<?php
+
+final class PhabricatorCalendarExportEditController
+ extends PhabricatorCalendarController {
+
+ public function handleRequest(AphrontRequest $request) {
+ return id(new PhabricatorCalendarExportEditEngine())
+ ->setController($this)
+ ->buildResponse();
+ }
+
+}
diff --git a/src/applications/calendar/controller/PhabricatorCalendarExportListController.php b/src/applications/calendar/controller/PhabricatorCalendarExportListController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/controller/PhabricatorCalendarExportListController.php
@@ -0,0 +1,27 @@
+<?php
+
+final class PhabricatorCalendarExportListController
+ extends PhabricatorCalendarController {
+
+ public function handleRequest(AphrontRequest $request) {
+ return id(new PhabricatorCalendarExportSearchEngine())
+ ->setController($this)
+ ->buildResponse();
+ }
+
+ protected function buildApplicationCrumbs() {
+ $crumbs = parent::buildApplicationCrumbs();
+
+ $doc_name = 'Calendar User Guide: Exporting Events';
+ $doc_href = PhabricatorEnv::getDoclink($doc_name);
+
+ $crumbs->addAction(
+ id(new PHUIListItemView())
+ ->setName(pht('Guide: Exporting Events'))
+ ->setIcon('fa-book')
+ ->setHref($doc_href));
+
+ return $crumbs;
+ }
+
+}
diff --git a/src/applications/calendar/editor/PhabricatorCalendarExportEditEngine.php b/src/applications/calendar/editor/PhabricatorCalendarExportEditEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/editor/PhabricatorCalendarExportEditEngine.php
@@ -0,0 +1,96 @@
+<?php
+
+final class PhabricatorCalendarExportEditEngine
+ extends PhabricatorEditEngine {
+
+ const ENGINECONST = 'calendar.export';
+
+ public function getEngineName() {
+ return pht('Calendar Exports');
+ }
+
+ public function isEngineConfigurable() {
+ return false;
+ }
+
+ public function getSummaryHeader() {
+ return pht('Configure Calendar Export Forms');
+ }
+
+ public function getSummaryText() {
+ return pht('Configure how users create and edit exports.');
+ }
+
+ public function getEngineApplicationClass() {
+ return 'PhabricatorCalendarApplication';
+ }
+
+ protected function newEditableObject() {
+ return PhabricatorCalendarExport::initializeNewCalendarExport(
+ $this->getViewer());
+ }
+
+ protected function newObjectQuery() {
+ return new PhabricatorCalendarExportQuery();
+ }
+
+ protected function getObjectCreateTitleText($object) {
+ return pht('Create New Export');
+ }
+
+ protected function getObjectEditTitleText($object) {
+ return pht('Edit Export: %s', $object->getName());
+ }
+
+ protected function getObjectEditShortText($object) {
+ return $object->getMonogram();
+ }
+
+ protected function getObjectCreateShortText() {
+ return pht('Create Export');
+ }
+
+ protected function getObjectName() {
+ return pht('Export');
+ }
+
+ protected function getObjectViewURI($object) {
+ return $object->getURI();
+ }
+
+ protected function getEditorURI() {
+ return $this->getApplication()->getApplicationURI('export/edit/');
+ }
+
+ protected function buildCustomEditFields($object) {
+ $viewer = $this->getViewer();
+
+ $fields = array(
+ id(new PhabricatorTextEditField())
+ ->setKey('name')
+ ->setLabel(pht('Name'))
+ ->setDescription(pht('Name of the export.'))
+ ->setIsRequired(true)
+ ->setTransactionType(
+ PhabricatorCalendarExportNameTransaction::TRANSACTIONTYPE)
+ ->setConduitDescription(pht('Rename the export.'))
+ ->setConduitTypeDescription(pht('New export name.'))
+ ->setValue($object->getName()),
+ id(new PhabricatorBoolEditField())
+ ->setKey('disabled')
+ ->setOptions(pht('Active'), pht('Disabled'))
+ ->setLabel(pht('Disabled'))
+ ->setDescription(pht('Disable the export.'))
+ ->setTransactionType(
+ PhabricatorCalendarExportDisableTransaction::TRANSACTIONTYPE)
+ ->setIsConduitOnly(true)
+ ->setConduitDescription(pht('Disable or restore the export.'))
+ ->setConduitTypeDescription(pht('True to cancel the export.'))
+ ->setValue($object->getIsDisabled()),
+ );
+
+ return $fields;
+ }
+
+
+}
diff --git a/src/applications/calendar/editor/PhabricatorCalendarExportEditor.php b/src/applications/calendar/editor/PhabricatorCalendarExportEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/editor/PhabricatorCalendarExportEditor.php
@@ -0,0 +1,14 @@
+<?php
+
+final class PhabricatorCalendarExportEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getEditorApplicationClass() {
+ return 'PhabricatorCalendarApplication';
+ }
+
+ public function getEditorObjectsDescription() {
+ return pht('Calendar Exports');
+ }
+
+}
diff --git a/src/applications/calendar/phid/PhabricatorCalendarExportPHIDType.php b/src/applications/calendar/phid/PhabricatorCalendarExportPHIDType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/phid/PhabricatorCalendarExportPHIDType.php
@@ -0,0 +1,50 @@
+<?php
+
+final class PhabricatorCalendarExportPHIDType extends PhabricatorPHIDType {
+
+ const TYPECONST = 'CEXP';
+
+ public function getTypeName() {
+ return pht('Calendar Export');
+ }
+
+ public function newObject() {
+ return new PhabricatorCalendarExport();
+ }
+
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorCalendarApplication';
+ }
+
+ protected function buildQueryForObjects(
+ PhabricatorObjectQuery $query,
+ array $phids) {
+
+ return id(new PhabricatorCalendarExportQuery())
+ ->withPHIDs($phids);
+ }
+
+ public function loadHandles(
+ PhabricatorHandleQuery $query,
+ array $handles,
+ array $objects) {
+
+ foreach ($handles as $phid => $handle) {
+ $export = $objects[$phid];
+
+ $id = $export->getID();
+ $name = $export->getName();
+ $uri = $export->getURI();
+
+ $handle
+ ->setName($name)
+ ->setFullName(pht('Calendar Export %s: %s', $id, $name))
+ ->setURI($uri);
+
+ if ($export->getIsDisabled()) {
+ $handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED);
+ }
+ }
+ }
+
+}
diff --git a/src/applications/calendar/query/PhabricatorCalendarExportQuery.php b/src/applications/calendar/query/PhabricatorCalendarExportQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/query/PhabricatorCalendarExportQuery.php
@@ -0,0 +1,81 @@
+<?php
+
+final class PhabricatorCalendarExportQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $ids;
+ private $phids;
+ private $authorPHIDs;
+ private $isDisabled;
+
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
+ public function withPHIDs(array $phids) {
+ $this->phids = $phids;
+ return $this;
+ }
+
+ public function withAuthorPHIDs(array $phids) {
+ $this->authorPHIDs = $phids;
+ return $this;
+ }
+
+ public function withIsDisabled($is_disabled) {
+ $this->isDisabled = $is_disabled;
+ return $this;
+ }
+
+ public function newResultObject() {
+ return new PhabricatorCalendarExport();
+ }
+
+ protected function loadPage() {
+ return $this->loadStandardPage($this->newResultObject());
+ }
+
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
+
+ if ($this->ids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'export.id IN (%Ld)',
+ $this->ids);
+ }
+
+ if ($this->phids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'export.phid IN (%Ls)',
+ $this->phids);
+ }
+
+ if ($this->authorPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'export.authorPHID IN (%Ls)',
+ $this->authorPHIDs);
+ }
+
+ if ($this->isDisabled !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'export.isDisabled = %d',
+ (int)$this->isDisabled);
+ }
+
+ return $where;
+ }
+
+ protected function getPrimaryTableAlias() {
+ return 'export';
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorCalendarApplication';
+ }
+
+}
diff --git a/src/applications/calendar/query/PhabricatorCalendarExportSearchEngine.php b/src/applications/calendar/query/PhabricatorCalendarExportSearchEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/query/PhabricatorCalendarExportSearchEngine.php
@@ -0,0 +1,109 @@
+<?php
+
+final class PhabricatorCalendarExportSearchEngine
+ extends PhabricatorApplicationSearchEngine {
+
+ public function getResultTypeDescription() {
+ return pht('Calendar Exports');
+ }
+
+ public function getApplicationClassName() {
+ return 'PhabricatorCalendarApplication';
+ }
+
+ public function newQuery() {
+ $viewer = $this->requireViewer();
+
+ return id(new PhabricatorCalendarExportQuery())
+ ->withAuthorPHIDs(array($viewer->getPHID()));
+ }
+
+ protected function buildCustomSearchFields() {
+ return array();
+ }
+
+ protected function buildQueryFromParameters(array $map) {
+ $query = $this->newQuery();
+
+ return $query;
+ }
+
+ protected function getURI($path) {
+ return '/calendar/export/'.$path;
+ }
+
+ protected function getBuiltinQueryNames() {
+ $names = array(
+ 'all' => pht('All Exports'),
+ );
+
+ return $names;
+ }
+
+ public function buildSavedQueryFromBuiltin($query_key) {
+ $query = $this->newSavedQuery();
+ $query->setQueryKey($query_key);
+
+ switch ($query_key) {
+ case 'all':
+ return $query;
+ }
+
+ return parent::buildSavedQueryFromBuiltin($query_key);
+ }
+
+ protected function renderResultList(
+ array $exports,
+ PhabricatorSavedQuery $query,
+ array $handles) {
+
+ assert_instances_of($exports, 'PhabricatorCalendarExport');
+ $viewer = $this->requireViewer();
+
+ $list = new PHUIObjectItemListView();
+ foreach ($exports as $export) {
+ $item = id(new PHUIObjectItemView())
+ ->setViewer($viewer)
+ ->setHeader($export->getName())
+ ->setHref($export->getURI());
+
+ if ($export->getIsDisabled()) {
+ $item->setDisabled(true);
+ }
+
+ $list->addItem($item);
+ }
+
+ $result = new PhabricatorApplicationSearchResultView();
+ $result->setObjectList($list);
+ $result->setNoDataString(pht('No exports found.'));
+
+ return $result;
+ }
+
+ protected function getNewUserBody() {
+ $doc_name = 'Calendar User Guide: Exporting Events';
+ $doc_href = PhabricatorEnv::getDoclink($doc_name);
+
+ $create_button = id(new PHUIButtonView())
+ ->setTag('a')
+ ->setIcon('fa-book white')
+ ->setText($doc_name)
+ ->setHref($doc_href)
+ ->setColor(PHUIButtonView::GREEN);
+
+ $icon = $this->getApplication()->getIcon();
+ $app_name = $this->getApplication()->getName();
+ $view = id(new PHUIBigInfoView())
+ ->setIcon('fa-download')
+ ->setTitle(pht('No Exports Configured'))
+ ->setDescription(
+ pht(
+ 'You have not set up any events for export from Calendar yet. '.
+ 'See the documentation for instructions on how to get started.'))
+ ->addAction($create_button);
+
+ return $view;
+ }
+
+}
diff --git a/src/applications/calendar/storage/PhabricatorCalendarExport.php b/src/applications/calendar/storage/PhabricatorCalendarExport.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/storage/PhabricatorCalendarExport.php
@@ -0,0 +1,144 @@
+<?php
+
+final class PhabricatorCalendarExport extends PhabricatorCalendarDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorApplicationTransactionInterface,
+ PhabricatorDestructibleInterface {
+
+ protected $name;
+ protected $authorPHID;
+ protected $policyMode;
+ protected $queryKey;
+ protected $secretKey;
+ protected $isDisabled = 0;
+
+ const MODE_PUBLIC = 'public';
+ const MODE_PRIVATE = 'private';
+
+ public static function initializeNewCalendarExport(PhabricatorUser $actor) {
+ return id(new self())
+ ->setAuthorPHID($actor->getPHID())
+ ->setPolicyMode(self::MODE_PRIVATE)
+ ->setIsDisabled(0);
+ }
+
+ protected function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ self::CONFIG_COLUMN_SCHEMA => array(
+ 'name' => 'text',
+ 'policyMode' => 'text64',
+ 'queryKey' => 'text64',
+ 'secretKey' => 'bytes20',
+ 'isDisabled' => 'bool',
+ ),
+ self::CONFIG_KEY_SCHEMA => array(
+ 'key_author' => array(
+ 'columns' => array('authorPHID'),
+ ),
+ 'key_secret' => array(
+ 'columns' => array('secretKey'),
+ 'unique' => true,
+ ),
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function getPHIDType() {
+ return PhabricatorCalendarExportPHIDType::TYPECONST;
+ }
+
+ public function save() {
+ if (!$this->getSecretKey()) {
+ $this->setSecretKey(Filesystem::readRandomCharacters(20));
+ }
+
+ return parent::save();
+ }
+
+ public function getURI() {
+ $id = $this->getID();
+ return "/calendar/export/{$id}/";
+ }
+
+ private static function getPolicyModeMap() {
+ return array(
+ self::MODE_PUBLIC => array(
+ 'name' => pht('Public'),
+ ),
+ self::MODE_PRIVATE => array(
+ 'name' => pht('Private'),
+ ),
+ );
+ }
+
+ private static function getPolicyModeSpec($const) {
+ return idx(self::getPolicyModeMap(), $const, array());
+ }
+
+ public static function getPolicyModeName($const) {
+ $map = self::getPolicyModeSpec($const);
+ return idx($map, 'name', $const);
+ }
+
+ public static function getPolicyModes() {
+ return array_keys(self::getPolicyModeMap());
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ );
+ }
+
+ public function getPolicy($capability) {
+ return $this->getAuthorPHID();
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return null;
+ }
+
+
+/* -( PhabricatorApplicationTransactionInterface )------------------------- */
+
+
+ public function getApplicationTransactionEditor() {
+ return new PhabricatorCalendarExportEditor();
+ }
+
+ public function getApplicationTransactionObject() {
+ return $this;
+ }
+
+ public function getApplicationTransactionTemplate() {
+ return new PhabricatorCalendarExportTransaction();
+ }
+
+ public function willRenderTimeline(
+ PhabricatorApplicationTransactionView $timeline,
+ AphrontRequest $request) {
+
+ return $timeline;
+ }
+
+
+/* -( PhabricatorDestructibleInterface )----------------------------------- */
+
+
+ public function destroyObjectPermanently(
+ PhabricatorDestructionEngine $engine) {
+ $this->delete();
+ }
+
+}
diff --git a/src/applications/calendar/storage/PhabricatorCalendarExportTransaction.php b/src/applications/calendar/storage/PhabricatorCalendarExportTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/storage/PhabricatorCalendarExportTransaction.php
@@ -0,0 +1,18 @@
+<?php
+
+final class PhabricatorCalendarExportTransaction
+ extends PhabricatorModularTransaction {
+
+ public function getApplicationName() {
+ return 'calendar';
+ }
+
+ public function getApplicationTransactionType() {
+ return PhabricatorCalendarExportPHIDType::TYPECONST;
+ }
+
+ public function getBaseTransactionClass() {
+ return 'PhabricatorCalendarExportTransactionType';
+ }
+
+}
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarExportDisableTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarExportDisableTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/xaction/PhabricatorCalendarExportDisableTransaction.php
@@ -0,0 +1,28 @@
+<?php
+
+final class PhabricatorCalendarExportDisableTransaction
+ extends PhabricatorCalendarExportTransactionType {
+
+ const TRANSACTIONTYPE = 'calendar.export.disable';
+
+ public function generateOldValue($object) {
+ return (int)$object->getIsDisabled();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setIsDisabled((int)$value);
+ }
+
+ public function getTitle() {
+ if ($this->getNewValue()) {
+ return pht(
+ '%s disabled this export.',
+ $this->renderAuthor());
+ } else {
+ return pht(
+ '%s enabled this export.',
+ $this->renderAuthor());
+ }
+ }
+
+}
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarExportModeTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarExportModeTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/xaction/PhabricatorCalendarExportModeTransaction.php
@@ -0,0 +1,54 @@
+<?php
+
+final class PhabricatorCalendarExportModeTransaction
+ extends PhabricatorCalendarExportTransactionType {
+
+ const TRANSACTIONTYPE = 'calendar.export.mode';
+
+ public function generateOldValue($object) {
+ return $object->getPolicyMode();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setPolicyMode($value);
+ }
+
+ public function getTitle() {
+ $old_value = $this->getOldValue();
+ $new_value = $this->getNewValue();
+
+ $old_name = PhabricatorCalendarExport::getPolicyModeName($old_value);
+ $new_name = PhabricatorCalendarExport::getPolicyModeName($new_value);
+
+ return pht(
+ '%s changed the policy mode for this export from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderValue($old_name),
+ $this->renderValue($new_name));
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ $valid = PhabricatorCalendarExport::getPolicyModes();
+ $valid = array_fuse($valid);
+
+ foreach ($xactions as $xaction) {
+ $value = $xaction->getNewValue();
+
+ if (isset($valid[$value])) {
+ continue;
+ }
+
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'Mode "%s" is not a valid policy mode. Valid modes are: %s.',
+ $value,
+ implode(', ', $valid)),
+ $xaction);
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarExportNameTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarExportNameTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/xaction/PhabricatorCalendarExportNameTransaction.php
@@ -0,0 +1,35 @@
+<?php
+
+final class PhabricatorCalendarExportNameTransaction
+ extends PhabricatorCalendarExportTransactionType {
+
+ const TRANSACTIONTYPE = 'calendar.export.name';
+
+ public function generateOldValue($object) {
+ return $object->getName();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setName($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s renamed this export from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Calendar exports must have a name.'));
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarExportQueryKeyTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarExportQueryKeyTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/xaction/PhabricatorCalendarExportQueryKeyTransaction.php
@@ -0,0 +1,51 @@
+<?php
+
+final class PhabricatorCalendarExportQueryKeyTransaction
+ extends PhabricatorCalendarExportTransactionType {
+
+ const TRANSACTIONTYPE = 'calendar.export.querykey';
+
+ public function generateOldValue($object) {
+ return $object->getQueryKey();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setQueryKey($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s changed the query for this export.',
+ $this->renderAuthor());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ foreach ($xactions as $xaction) {
+ $value = $xaction->getNewValue();
+
+ $query = id(new PhabricatorSavedQueryQuery())
+ ->withEngineClassNames(array('PhabricatorCalendarEventSearchEngine'))
+ ->withQueryKeys(array($value))
+ ->executeOne();
+ if ($query) {
+ continue;
+ }
+
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'Query key "%s" does not identify a valid event query.',
+ $value),
+ $xaction);
+ }
+
+ if ($this->isEmptyTextTransaction($object->getQueryKey(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Calendar exports must have a query key.'));
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarExportTransactionType.php b/src/applications/calendar/xaction/PhabricatorCalendarExportTransactionType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/xaction/PhabricatorCalendarExportTransactionType.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class PhabricatorCalendarExportTransactionType
+ extends PhabricatorModularTransactionType {}
diff --git a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php
--- a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php
+++ b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php
@@ -421,7 +421,7 @@
'you need to get done. Tasks assigned to you will appear here.'))
->addAction($create_button);
- return $view;
+ return $view;
}
}
diff --git a/src/docs/user/userguide/calendar_exports.diviner b/src/docs/user/userguide/calendar_exports.diviner
new file mode 100644
--- /dev/null
+++ b/src/docs/user/userguide/calendar_exports.diviner
@@ -0,0 +1,12 @@
+@title Calendar User Guide: Exporting Events
+@group userguide
+
+Exporting events to other calendars.
+
+Overview
+========
+
+IMPORTANT: Calendar is a prototype application. See
+@{article:User Guide: Prototype Applications}.
+
+Coming soon!
diff --git a/src/infrastructure/storage/lisk/LiskDAO.php b/src/infrastructure/storage/lisk/LiskDAO.php
--- a/src/infrastructure/storage/lisk/LiskDAO.php
+++ b/src/infrastructure/storage/lisk/LiskDAO.php
@@ -1339,11 +1339,12 @@
* @task hook
*/
public function generatePHID() {
- throw new Exception(
- pht(
- 'To use %s, you need to overload %s to perform PHID generation.',
- 'CONFIG_AUX_PHID',
- 'generatePHID()'));
+ $type = $this->getPHIDType();
+ return PhabricatorPHID::generateNewPHID($type);
+ }
+
+ public function getPHIDType() {
+ throw new PhutilMethodNotImplementedException();
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Oct 24, 9:32 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6720778
Default Alt Text
D16675.diff (30 KB)
Attached To
Mode
D16675: Rough in most of Calendar exports
Attached
Detach File
Event Timeline
Log In to Comment