Page MenuHomePhabricator

D16730.diff
No OneTemporary

D16730.diff

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

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)

Event Timeline