Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13976304
D16730.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
D16730.diff
View Options
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
@@ -2100,7 +2100,9 @@
'PhabricatorCalendarExportViewController' => 'applications/calendar/controller/PhabricatorCalendarExportViewController.php',
'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
+ 'PhabricatorCalendarICSFileImportEngine' => 'applications/calendar/import/PhabricatorCalendarICSFileImportEngine.php',
'PhabricatorCalendarICSImportEngine' => 'applications/calendar/import/PhabricatorCalendarICSImportEngine.php',
+ 'PhabricatorCalendarICSURIImportEngine' => 'applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php',
'PhabricatorCalendarICSWriter' => 'applications/calendar/util/PhabricatorCalendarICSWriter.php',
'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php',
'PhabricatorCalendarImport' => 'applications/calendar/storage/PhabricatorCalendarImport.php',
@@ -2117,9 +2119,11 @@
'PhabricatorCalendarImportEmptyLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportEmptyLogType.php',
'PhabricatorCalendarImportEngine' => 'applications/calendar/import/PhabricatorCalendarImportEngine.php',
'PhabricatorCalendarImportEpochLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportEpochLogType.php',
+ 'PhabricatorCalendarImportFetchLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportFetchLogType.php',
'PhabricatorCalendarImportFrequencyLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportFrequencyLogType.php',
'PhabricatorCalendarImportICSFileTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportICSFileTransaction.php',
'PhabricatorCalendarImportICSLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php',
+ 'PhabricatorCalendarImportICSURITransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportICSURITransaction.php',
'PhabricatorCalendarImportIgnoredNodeLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportIgnoredNodeLogType.php',
'PhabricatorCalendarImportListController' => 'applications/calendar/controller/PhabricatorCalendarImportListController.php',
'PhabricatorCalendarImportLog' => 'applications/calendar/storage/PhabricatorCalendarImportLog.php',
@@ -6931,7 +6935,9 @@
'PhabricatorCalendarExportViewController' => 'PhabricatorCalendarController',
'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
+ 'PhabricatorCalendarICSFileImportEngine' => 'PhabricatorCalendarICSImportEngine',
'PhabricatorCalendarICSImportEngine' => 'PhabricatorCalendarImportEngine',
+ 'PhabricatorCalendarICSURIImportEngine' => 'PhabricatorCalendarICSImportEngine',
'PhabricatorCalendarICSWriter' => 'Phobject',
'PhabricatorCalendarIconSet' => 'PhabricatorIconSet',
'PhabricatorCalendarImport' => array(
@@ -6953,9 +6959,11 @@
'PhabricatorCalendarImportEmptyLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportEngine' => 'Phobject',
'PhabricatorCalendarImportEpochLogType' => 'PhabricatorCalendarImportLogType',
+ 'PhabricatorCalendarImportFetchLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportFrequencyLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportICSFileTransaction' => 'PhabricatorCalendarImportTransactionType',
'PhabricatorCalendarImportICSLogType' => 'PhabricatorCalendarImportLogType',
+ 'PhabricatorCalendarImportICSURITransaction' => 'PhabricatorCalendarImportTransactionType',
'PhabricatorCalendarImportIgnoredNodeLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportListController' => 'PhabricatorCalendarController',
'PhabricatorCalendarImportLog' => array(
diff --git a/src/applications/calendar/import/PhabricatorCalendarICSImportEngine.php b/src/applications/calendar/import/PhabricatorCalendarICSFileImportEngine.php
copy from src/applications/calendar/import/PhabricatorCalendarICSImportEngine.php
copy to src/applications/calendar/import/PhabricatorCalendarICSFileImportEngine.php
--- a/src/applications/calendar/import/PhabricatorCalendarICSImportEngine.php
+++ b/src/applications/calendar/import/PhabricatorCalendarICSFileImportEngine.php
@@ -1,9 +1,9 @@
<?php
-final class PhabricatorCalendarICSImportEngine
- extends PhabricatorCalendarImportEngine {
+final class PhabricatorCalendarICSFileImportEngine
+ extends PhabricatorCalendarICSImportEngine {
- const ENGINETYPE = 'ics';
+ const ENGINETYPE = 'icsfile';
public function getImportEngineName() {
return pht('Import .ics File');
@@ -17,7 +17,6 @@
return pht('Import an event in ".ics" (iCalendar) format.');
}
-
public function appendImportProperties(
PhabricatorUser $viewer,
PhabricatorCalendarImport $import,
@@ -80,27 +79,7 @@
$data = $file->loadFileData();
- $parser = new PhutilICSParser();
-
- try {
- $document = $parser->parseICSData($data);
- } catch (PhutilICSParserException $ex) {
- // TODO: In theory, it would be nice to store these in a fully abstract
- // form so they can be translated at display time. As-is, we'll store the
- // error messages in whatever language we were using when the parser
- // failure occurred.
-
- $import->newLogMessage(
- PhabricatorCalendarImportICSLogType::LOGTYPE,
- array(
- 'ics.code' => $ex->getParserFailureCode(),
- 'ics.message' => $ex->getMessage(),
- ));
-
- $document = null;
- }
-
- return $this->importEventDocument($viewer, $import, $document);
+ return $this->importICSData($viewer, $import, $data);
}
diff --git a/src/applications/calendar/import/PhabricatorCalendarICSImportEngine.php b/src/applications/calendar/import/PhabricatorCalendarICSImportEngine.php
--- a/src/applications/calendar/import/PhabricatorCalendarICSImportEngine.php
+++ b/src/applications/calendar/import/PhabricatorCalendarICSImportEngine.php
@@ -1,84 +1,12 @@
<?php
-final class PhabricatorCalendarICSImportEngine
+abstract class PhabricatorCalendarICSImportEngine
extends PhabricatorCalendarImportEngine {
- const ENGINETYPE = 'ics';
-
- public function getImportEngineName() {
- return pht('Import .ics File');
- }
-
- public function getImportEngineTypeName() {
- return pht('.ics File');
- }
-
- public function getImportEngineHint() {
- return pht('Import an event in ".ics" (iCalendar) format.');
- }
-
-
- public function appendImportProperties(
+ final protected function importICSData(
PhabricatorUser $viewer,
PhabricatorCalendarImport $import,
- PHUIPropertyListView $properties) {
-
- $phid_key = PhabricatorCalendarImportICSFileTransaction::PARAMKEY_FILE;
- $file_phid = $import->getParameter($phid_key);
-
- $properties->addProperty(
- pht('Source File'),
- $viewer->renderHandle($file_phid));
- }
-
- public function newEditEngineFields(
- PhabricatorEditEngine $engine,
- PhabricatorCalendarImport $import) {
- $fields = array();
-
- if ($engine->getIsCreate()) {
- $fields[] = id(new PhabricatorFileEditField())
- ->setKey('icsFilePHID')
- ->setLabel(pht('ICS File'))
- ->setDescription(pht('ICS file to import.'))
- ->setTransactionType(
- PhabricatorCalendarImportICSFileTransaction::TRANSACTIONTYPE)
- ->setConduitDescription(pht('File PHID to import.'))
- ->setConduitTypeDescription(pht('File PHID.'));
- }
-
- return $fields;
- }
-
- public function getDisplayName(PhabricatorCalendarImport $import) {
- $filename_key = PhabricatorCalendarImportICSFileTransaction::PARAMKEY_NAME;
- $filename = $import->getParameter($filename_key);
- if (strlen($filename)) {
- return pht('ICS File "%s"', $filename);
- } else {
- return pht('ICS File');
- }
- }
-
- public function didCreateImport(
- PhabricatorUser $viewer,
- PhabricatorCalendarImport $import) {
-
- $phid_key = PhabricatorCalendarImportICSFileTransaction::PARAMKEY_FILE;
- $file_phid = $import->getParameter($phid_key);
-
- $file = id(new PhabricatorFileQuery())
- ->setViewer($viewer)
- ->withPHIDs(array($file_phid))
- ->executeOne();
- if (!$file) {
- throw new Exception(
- pht(
- 'Unable to load file ("%s") for import.',
- $file_phid));
- }
-
- $data = $file->loadFileData();
+ $data) {
$parser = new PhutilICSParser();
@@ -103,21 +31,4 @@
return $this->importEventDocument($viewer, $import, $document);
}
-
- public function canDisable(
- PhabricatorUser $viewer,
- PhabricatorCalendarImport $import) {
- return false;
- }
-
- public function explainCanDisable(
- PhabricatorUser $viewer,
- PhabricatorCalendarImport $import) {
- return pht(
- 'You can not disable import of an ICS file because the entire import '.
- 'occurs immediately when you upload the file. There is no further '.
- 'activity to disable.');
- }
-
-
}
diff --git a/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php b/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php
@@ -0,0 +1,111 @@
+<?php
+
+final class PhabricatorCalendarICSURIImportEngine
+ extends PhabricatorCalendarICSImportEngine {
+
+ const ENGINETYPE = 'icsuri';
+
+ public function getImportEngineName() {
+ return pht('Import .ics URI');
+ }
+
+ public function getImportEngineTypeName() {
+ return pht('.ics URI');
+ }
+
+ public function getImportEngineHint() {
+ return pht('Import or subscribe to a calendar in .ics format by URI.');
+ }
+
+ public function appendImportProperties(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImport $import,
+ PHUIPropertyListView $properties) {
+
+ $uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI;
+ $uri = $import->getParameter($uri_key);
+
+ // Since the URI may contain a secret hash, don't show it to users who
+ // can not edit the import.
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $import,
+ PhabricatorPolicyCapability::CAN_EDIT);
+ if (!$can_edit) {
+ $uri_display = phutil_tag('em', array(), pht('Restricted'));
+ } else if (!PhabricatorEnv::isValidRemoteURIForLink($uri)) {
+ $uri_display = $uri;
+ } else {
+ $uri_display = phutil_tag(
+ 'a',
+ array(
+ 'href' => $uri,
+ 'target' => '_blank',
+ ),
+ $uri);
+ }
+
+ $properties->addProperty(pht('Source URI'), $uri_display);
+ }
+
+ public function newEditEngineFields(
+ PhabricatorEditEngine $engine,
+ PhabricatorCalendarImport $import) {
+ $fields = array();
+
+ if ($engine->getIsCreate()) {
+ $fields[] = id(new PhabricatorTextEditField())
+ ->setKey('uri')
+ ->setLabel(pht('URI'))
+ ->setDescription(pht('URI to import.'))
+ ->setTransactionType(
+ PhabricatorCalendarImportICSURITransaction::TRANSACTIONTYPE)
+ ->setConduitDescription(pht('URI to import.'))
+ ->setConduitTypeDescription(pht('New URI.'));
+ }
+
+ return $fields;
+ }
+
+ public function getDisplayName(PhabricatorCalendarImport $import) {
+ return pht('ICS URI');
+ }
+
+ public function didCreateImport(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImport $import) {
+
+ $uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI;
+ $uri = $import->getParameter($uri_key);
+
+ PhabricatorSystemActionEngine::willTakeAction(
+ array($viewer->getPHID()),
+ new PhabricatorFilesOutboundRequestAction(),
+ 1);
+
+ $file = PhabricatorFile::newFromFileDownload(
+ $uri,
+ array(
+ 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
+ 'authorPHID' => $import->getAuthorPHID(),
+ 'canCDN' => true,
+ ));
+
+ $import->newLogMessage(
+ PhabricatorCalendarImportFetchLogType::LOGTYPE,
+ array(
+ 'file.phid' => $file->getPHID(),
+ ));
+
+ $data = $file->loadFileData();
+
+ return $this->importICSData($viewer, $import, $data);
+ }
+
+ public function canDisable(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImport $import) {
+ return true;
+ }
+
+}
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportFetchLogType.php
copy from src/applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php
copy to src/applications/calendar/importlog/PhabricatorCalendarImportFetchLogType.php
--- a/src/applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportFetchLogType.php
@@ -1,36 +1,33 @@
<?php
-final class PhabricatorCalendarImportICSLogType
+final class PhabricatorCalendarImportFetchLogType
extends PhabricatorCalendarImportLogType {
- const LOGTYPE = 'ics';
+ const LOGTYPE = 'fetch';
public function getDisplayType(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
- return pht('ICS Parse Error');
+ return pht('Fetched Calendar');
}
public function getDisplayDescription(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
- return pht(
- 'Failed to parse ICS file ("%s"): %s',
- $log->getParameter('ics.code'),
- $log->getParameter('ics.message'));
- }
+ return $viewer->renderHandle($log->getParameter('file.phid'));
+ }
public function getDisplayIcon(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
- return 'fa-file';
+ return 'fa-download';
}
public function getDisplayColor(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
- return 'red';
+ return 'green';
}
}
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php
--- a/src/applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php
@@ -15,7 +15,7 @@
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
return pht(
- 'Failed to parse ICS file ("%s"): %s',
+ 'Failed to parse ICS data ("%s"): %s',
$log->getParameter('ics.code'),
$log->getParameter('ics.message'));
}
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarImportICSFileTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarImportICSFileTransaction.php
--- a/src/applications/calendar/xaction/PhabricatorCalendarImportICSFileTransaction.php
+++ b/src/applications/calendar/xaction/PhabricatorCalendarImportICSFileTransaction.php
@@ -34,7 +34,7 @@
$viewer = $this->getActor();
$errors = array();
- $ics_type = PhabricatorCalendarICSImportEngine::ENGINETYPE;
+ $ics_type = PhabricatorCalendarICSFileImportEngine::ENGINETYPE;
$import_type = $object->getEngine()->getImportEngineType();
if ($import_type != $ics_type) {
if (!$xactions) {
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarImportICSURITransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarImportICSURITransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/xaction/PhabricatorCalendarImportICSURITransaction.php
@@ -0,0 +1,73 @@
+<?php
+
+final class PhabricatorCalendarImportICSURITransaction
+ extends PhabricatorCalendarImportTransactionType {
+
+ const TRANSACTIONTYPE = 'calendar.import.ics.uri';
+ const PARAMKEY_URI = 'ics.uri';
+
+ public function generateOldValue($object) {
+ return $object->getParameter(self::PARAMKEY_URI);
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setParameter(self::PARAMKEY_URI, $value);
+ }
+
+ public function getTitle() {
+ // NOTE: This transaction intentionally does not disclose the actual
+ // URI.
+ return pht(
+ '%s updated the import URI.',
+ $this->renderAuthor());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $viewer = $this->getActor();
+ $errors = array();
+
+ $ics_type = PhabricatorCalendarICSURIImportEngine::ENGINETYPE;
+ $import_type = $object->getEngine()->getImportEngineType();
+ if ($import_type != $ics_type) {
+ if (!$xactions) {
+ return $errors;
+ }
+
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'You can not attach an ICS URI to an import type other than '.
+ 'an ICS URI import (type is "%s").',
+ $import_type));
+
+ return $errors;
+ }
+
+ $new_value = $object->getParameter(self::PARAMKEY_URI);
+ foreach ($xactions as $xaction) {
+ $new_value = $xaction->getNewValue();
+ if (!strlen($new_value)) {
+ continue;
+ }
+
+ try {
+ PhabricatorEnv::requireValidRemoteURIForFetch(
+ $new_value,
+ array(
+ 'http',
+ 'https',
+ ));
+ } catch (Exception $ex) {
+ $errors[] = $this->newInvalidError(
+ $ex->getMessage(),
+ $xaction);
+ }
+ }
+
+ if (!strlen($new_value)) {
+ $errors[] = $this->newRequiredError(
+ pht('You must select an ".ics" URI to import.'));
+ }
+
+ return $errors;
+ }
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 19, 1:40 PM (4 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6721442
Default Alt Text
D16730.diff (17 KB)
Attached To
Mode
D16730: Add a URI-based ICS import source engine
Attached
Detach File
Event Timeline
Log In to Comment