Page MenuHomePhabricator

D16704.id40215.diff
No OneTemporary

D16704.id40215.diff

diff --git a/resources/sql/autopatches/20161013.cal.01.importlog.sql b/resources/sql/autopatches/20161013.cal.01.importlog.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20161013.cal.01.importlog.sql
@@ -0,0 +1,8 @@
+CREATE TABLE {$NAMESPACE}_calendar.calendar_importlog (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ importPHID VARBINARY(64) NOT NULL,
+ parameters LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ KEY `key_import` (`importPHID`)
+) 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
@@ -2102,21 +2102,31 @@
'PhabricatorCalendarICSWriter' => 'applications/calendar/util/PhabricatorCalendarICSWriter.php',
'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php',
'PhabricatorCalendarImport' => 'applications/calendar/storage/PhabricatorCalendarImport.php',
+ 'PhabricatorCalendarImportDefaultLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportDefaultLogType.php',
'PhabricatorCalendarImportDisableController' => 'applications/calendar/controller/PhabricatorCalendarImportDisableController.php',
'PhabricatorCalendarImportDisableTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportDisableTransaction.php',
+ 'PhabricatorCalendarImportDuplicateLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportDuplicateLogType.php',
'PhabricatorCalendarImportEditController' => 'applications/calendar/controller/PhabricatorCalendarImportEditController.php',
'PhabricatorCalendarImportEditEngine' => 'applications/calendar/editor/PhabricatorCalendarImportEditEngine.php',
'PhabricatorCalendarImportEditor' => 'applications/calendar/editor/PhabricatorCalendarImportEditor.php',
+ 'PhabricatorCalendarImportEmptyLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportEmptyLogType.php',
'PhabricatorCalendarImportEngine' => 'applications/calendar/import/PhabricatorCalendarImportEngine.php',
'PhabricatorCalendarImportICSFileTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportICSFileTransaction.php',
+ 'PhabricatorCalendarImportIgnoredNodeLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportIgnoredNodeLogType.php',
'PhabricatorCalendarImportListController' => 'applications/calendar/controller/PhabricatorCalendarImportListController.php',
+ 'PhabricatorCalendarImportLog' => 'applications/calendar/storage/PhabricatorCalendarImportLog.php',
+ 'PhabricatorCalendarImportLogQuery' => 'applications/calendar/query/PhabricatorCalendarImportLogQuery.php',
+ 'PhabricatorCalendarImportLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportLogType.php',
'PhabricatorCalendarImportNameTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportNameTransaction.php',
+ 'PhabricatorCalendarImportOriginalLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportOriginalLogType.php',
+ 'PhabricatorCalendarImportOrphanLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportOrphanLogType.php',
'PhabricatorCalendarImportPHIDType' => 'applications/calendar/phid/PhabricatorCalendarImportPHIDType.php',
'PhabricatorCalendarImportQuery' => 'applications/calendar/query/PhabricatorCalendarImportQuery.php',
'PhabricatorCalendarImportSearchEngine' => 'applications/calendar/query/PhabricatorCalendarImportSearchEngine.php',
'PhabricatorCalendarImportTransaction' => 'applications/calendar/storage/PhabricatorCalendarImportTransaction.php',
'PhabricatorCalendarImportTransactionQuery' => 'applications/calendar/query/PhabricatorCalendarImportTransactionQuery.php',
'PhabricatorCalendarImportTransactionType' => 'applications/calendar/xaction/PhabricatorCalendarImportTransactionType.php',
+ 'PhabricatorCalendarImportUpdateLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportUpdateLogType.php',
'PhabricatorCalendarImportViewController' => 'applications/calendar/controller/PhabricatorCalendarImportViewController.php',
'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php',
'PhabricatorCalendarReplyHandler' => 'applications/calendar/mail/PhabricatorCalendarReplyHandler.php',
@@ -6906,21 +6916,35 @@
'PhabricatorApplicationTransactionInterface',
'PhabricatorDestructibleInterface',
),
+ 'PhabricatorCalendarImportDefaultLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportDisableController' => 'PhabricatorCalendarController',
'PhabricatorCalendarImportDisableTransaction' => 'PhabricatorCalendarImportTransactionType',
+ 'PhabricatorCalendarImportDuplicateLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportEditController' => 'PhabricatorCalendarController',
'PhabricatorCalendarImportEditEngine' => 'PhabricatorEditEngine',
'PhabricatorCalendarImportEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'PhabricatorCalendarImportEmptyLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportEngine' => 'Phobject',
'PhabricatorCalendarImportICSFileTransaction' => 'PhabricatorCalendarImportTransactionType',
+ 'PhabricatorCalendarImportIgnoredNodeLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportListController' => 'PhabricatorCalendarController',
+ 'PhabricatorCalendarImportLog' => array(
+ 'PhabricatorCalendarDAO',
+ 'PhabricatorPolicyInterface',
+ 'PhabricatorDestructibleInterface',
+ ),
+ 'PhabricatorCalendarImportLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhabricatorCalendarImportLogType' => 'Phobject',
'PhabricatorCalendarImportNameTransaction' => 'PhabricatorCalendarImportTransactionType',
+ 'PhabricatorCalendarImportOriginalLogType' => 'PhabricatorCalendarImportLogType',
+ 'PhabricatorCalendarImportOrphanLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportPHIDType' => 'PhabricatorPHIDType',
'PhabricatorCalendarImportQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorCalendarImportSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorCalendarImportTransaction' => 'PhabricatorModularTransaction',
'PhabricatorCalendarImportTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorCalendarImportTransactionType' => 'PhabricatorModularTransactionType',
+ 'PhabricatorCalendarImportUpdateLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportViewController' => 'PhabricatorCalendarController',
'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'PhabricatorCalendarReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
diff --git a/src/applications/calendar/controller/PhabricatorCalendarImportViewController.php b/src/applications/calendar/controller/PhabricatorCalendarImportViewController.php
--- a/src/applications/calendar/controller/PhabricatorCalendarImportViewController.php
+++ b/src/applications/calendar/controller/PhabricatorCalendarImportViewController.php
@@ -30,12 +30,14 @@
$curtain = $this->buildCurtain($import);
$details = $this->buildPropertySection($import);
+ $log_messages = $this->buildLogMessages($import);
$imported_events = $this->buildImportedEvents($import);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setMainColumn(
array(
+ $log_messages,
$imported_events,
$timeline,
))
@@ -134,8 +136,70 @@
return $properties;
}
- private function buildImportedEvents(
- PhabricatorCalendarImport $import) {
+ private function buildLogMessages(PhabricatorCalendarImport $import) {
+ $viewer = $this->getViewer();
+
+ $logs = id(new PhabricatorCalendarImportLogQuery())
+ ->setViewer($viewer)
+ ->withImportPHIDs(array($import->getPHID()))
+ ->setLimit(25)
+ ->execute();
+
+ $rows = array();
+ foreach ($logs as $log) {
+ $icon = $log->getDisplayIcon($viewer);
+ $color = $log->getDisplayColor($viewer);
+ $name = $log->getDisplayType($viewer);
+ $description = $log->getDisplayDescription($viewer);
+
+ $rows[] = array(
+ $log->getID(),
+ id(new PHUIIconView())->setIcon($icon, $color),
+ $name,
+ $description,
+ phabricator_datetime($log->getDateCreated(), $viewer),
+ );
+ }
+
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(
+ array(
+ pht('ID'),
+ null,
+ pht('Type'),
+ pht('Mesage'),
+ pht('Date'),
+ ))
+ ->setColumnClasses(
+ array(
+ null,
+ null,
+ 'pri',
+ 'wide',
+ null,
+ ));
+
+ $all_uri = $this->getApplicationURI('import/log/');
+ $all_uri = (string)id(new PhutilURI($all_uri))
+ ->setQueryParam('importSourcePHID', $import->getPHID());
+
+ $all_button = id(new PHUIButtonView())
+ ->setTag('a')
+ ->setText(pht('View All'))
+ ->setIcon('fa-search')
+ ->setHref($all_uri);
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader(pht('Log Messages'))
+ ->addActionLink($all_button);
+
+ return id(new PHUIObjectBoxView())
+ ->setHeader($header)
+ ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
+ ->setTable($table);
+ }
+
+ private function buildImportedEvents(PhabricatorCalendarImport $import) {
$viewer = $this->getViewer();
$engine = id(new PhabricatorCalendarEventSearchEngine())
diff --git a/src/applications/calendar/import/PhabricatorCalendarImportEngine.php b/src/applications/calendar/import/PhabricatorCalendarImportEngine.php
--- a/src/applications/calendar/import/PhabricatorCalendarImportEngine.php
+++ b/src/applications/calendar/import/PhabricatorCalendarImportEngine.php
@@ -49,8 +49,13 @@
$nodes = array();
foreach ($root->getChildren() as $document) {
foreach ($document->getChildren() as $node) {
- if ($node->getNodeType() != $event_type) {
- // TODO: Warn that we ignored this.
+ $node_type = $node->getNodeType();
+ if ($node_type != $event_type) {
+ $import->newLogMessage(
+ PhabricatorCalendarImportIgnoredNodeLogType::LOGTYPE,
+ array(
+ 'node.type' => $node_type,
+ ));
continue;
}
@@ -59,16 +64,62 @@
}
$node_map = array();
- $parent_uids = array();
foreach ($nodes as $node) {
$full_uid = $this->getFullNodeUID($node);
if (isset($node_map[$full_uid])) {
- // TODO: Warn that we got a duplicate.
+ $import->newLogMessage(
+ PhabricatorCalendarImportDuplicateLogType::LOGTYPE,
+ array(
+ 'uid.full' => $full_uid,
+ ));
continue;
}
$node_map[$full_uid] = $node;
}
+ // If we already know about some of these events and they were created
+ // here, we're not going to import it again. This can happen if a user
+ // exports an event and then tries to import it again. This is probably
+ // not what they meant to do and this pathway generally leads to madness.
+ $likely_phids = array();
+ foreach ($node_map as $full_uid => $node) {
+ $uid = $node->getUID();
+ $matches = null;
+ if (preg_match('/^(PHID-.*)@(.*)\z/', $uid, $matches)) {
+ $likely_phids[$full_uid] = $matches[1];
+ }
+ }
+
+ if ($likely_phids) {
+ // NOTE: We're using the omnipotent viewer here because we don't want
+ // to collide with events that already exist, even if you can't see
+ // them.
+ $events = id(new PhabricatorCalendarEventQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withPHIDs($likely_phids)
+ ->execute();
+ $events = mpull($events, null, 'getPHID');
+ foreach ($node_map as $full_uid => $node) {
+ $phid = idx($likely_phids, $full_uid);
+ if (!$phid) {
+ continue;
+ }
+
+ $event = idx($events, $phid);
+ if (!$event) {
+ continue;
+ }
+
+ $import->newLogMessage(
+ PhabricatorCalendarImportOriginalLogType::LOGTYPE,
+ array(
+ 'phid' => $event->getPHID(),
+ ));
+
+ unset($node_map[$full_uid]);
+ }
+ }
+
if ($node_map) {
$events = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
@@ -114,7 +165,12 @@
// does not exist or we're going to delete it anyway. We just drop
// this node.
- // TODO: Warn that we got rid of an event with no parent.
+ $import->newLogMessage(
+ PhabricatorCalendarImportOrphanLogType::LOGTYPE,
+ array(
+ 'uid.full' => $full_uid,
+ 'uid.parent' => $parent_uid,
+ ));
continue;
}
@@ -130,6 +186,10 @@
$content_source = PhabricatorContentSource::newForSource(
PhabricatorWebContentSource::SOURCECONST);
+ // NOTE: We're using the omnipotent user here because imported events are
+ // otherwise immutable.
+ $edit_actor = PhabricatorUser::getOmnipotentUser();
+
$update_map = array_select_keys($update_map, $insert_order);
foreach ($update_map as $full_uid => $event) {
$parent_uid = $this->getParentNodeUID($node_map[$full_uid]);
@@ -144,13 +204,28 @@
$event_xactions = $xactions[$full_uid];
$editor = id(new PhabricatorCalendarEventEditor())
- ->setActor($viewer)
+ ->setActor($edit_actor)
->setActingAsPHID($import->getPHID())
->setContentSource($content_source)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
+ $is_new = !$event->getID();
+
$editor->applyTransactions($event, $event_xactions);
+
+ $import->newLogMessage(
+ PhabricatorCalendarImportUpdateLogType::LOGTYPE,
+ array(
+ 'new' => $is_new,
+ 'phid' => $event->getPHID(),
+ ));
+ }
+
+ if (!$update_map) {
+ $import->newLogMessage(
+ PhabricatorCalendarImportEmptyLogType::LOGTYPE,
+ array());
}
// TODO: When the source is a subscription-based ICS file or some other
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportDefaultLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportDefaultLogType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportDefaultLogType.php
@@ -0,0 +1,20 @@
+<?php
+
+final class PhabricatorCalendarImportDefaultLogType
+ extends PhabricatorCalendarImportLogType {
+
+ const LOGTYPE = 'default';
+
+ public function getDisplayType(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+
+ $type = $log->getParameter('type');
+ if (strlen($type)) {
+ return pht('Unknown Message "%s"', $type);
+ } else {
+ return pht('Unknown Message');
+ }
+ }
+
+}
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportDuplicateLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportDuplicateLogType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportDuplicateLogType.php
@@ -0,0 +1,23 @@
+<?php
+
+final class PhabricatorCalendarImportDuplicateLogType
+ extends PhabricatorCalendarImportLogType {
+
+ const LOGTYPE = 'duplicate';
+
+ public function getDisplayType(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return pht('Duplicate Event');
+ }
+
+ public function getDisplayDescription(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ $duplicate_uid = $log->getParameter('uid.full');
+ return pht(
+ 'Ignored duplicate event "%s" present in source.',
+ $duplicate_uid);
+ }
+
+}
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportEmptyLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportEmptyLogType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportEmptyLogType.php
@@ -0,0 +1,32 @@
+<?php
+
+final class PhabricatorCalendarImportEmptyLogType
+ extends PhabricatorCalendarImportLogType {
+
+ const LOGTYPE = 'empty';
+
+ public function getDisplayType(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return pht('No Events Imported');
+ }
+
+ public function getDisplayDescription(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return pht('Found no valid events to import.');
+ }
+
+ public function getDisplayIcon(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return 'fa-ban';
+ }
+
+ public function getDisplayColor(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return 'red';
+ }
+
+}
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportIgnoredNodeLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportIgnoredNodeLogType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportIgnoredNodeLogType.php
@@ -0,0 +1,23 @@
+<?php
+
+final class PhabricatorCalendarImportIgnoredNodeLogType
+ extends PhabricatorCalendarImportLogType {
+
+ const LOGTYPE = 'nodetype';
+
+ public function getDisplayType(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return pht('Ignored Node');
+ }
+
+ public function getDisplayDescription(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ $node_type = $log->getParameter('node.type');
+ return pht(
+ 'Ignored unsupported "%s" node present in source.',
+ $node_type);
+ }
+
+}
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportLogType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportLogType.php
@@ -0,0 +1,39 @@
+<?php
+
+abstract class PhabricatorCalendarImportLogType
+ extends Phobject {
+
+ final public function getLogTypeConstant() {
+ return $this->getPhobjectClassConstant('LOGTYPE', 64);
+ }
+
+ final public static function getAllLogTypes() {
+ return id(new PhutilClassMapQuery())
+ ->setAncestorClass(__CLASS__)
+ ->setUniqueMethod('getLogTypeConstant')
+ ->execute();
+ }
+
+ abstract public function getDisplayType(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log);
+
+ public function getDisplayIcon(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return 'fa-warning';
+ }
+
+ public function getDisplayColor(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return 'yellow';
+ }
+
+ public function getDisplayDescription(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return null;
+ }
+
+}
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportOriginalLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportOriginalLogType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportOriginalLogType.php
@@ -0,0 +1,26 @@
+<?php
+
+final class PhabricatorCalendarImportOriginalLogType
+ extends PhabricatorCalendarImportLogType {
+
+ const LOGTYPE = 'original';
+
+ public function getDisplayType(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return pht('Original Event');
+ }
+
+ public function getDisplayDescription(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+
+ $phid = $log->getParameter('phid');
+
+ return pht(
+ 'Ignored an event (%s) because the original version of this event '.
+ 'was created here.',
+ $viewer->renderHandle($phid));
+ }
+
+}
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportOrphanLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportOrphanLogType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportOrphanLogType.php
@@ -0,0 +1,25 @@
+<?php
+
+final class PhabricatorCalendarImportOrphanLogType
+ extends PhabricatorCalendarImportLogType {
+
+ const LOGTYPE = 'orphan';
+
+ public function getDisplayType(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return pht('Orphan');
+ }
+
+ public function getDisplayDescription(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ $child_uid = $log->getParameter('uid.full');
+ $parent_uid = $log->getParameter('uid.parent');
+ return pht(
+ 'Found orphaned child event ("%s") without a parent event ("%s").',
+ $child_uid,
+ $parent_uid);
+ }
+
+}
diff --git a/src/applications/calendar/importlog/PhabricatorCalendarImportUpdateLogType.php b/src/applications/calendar/importlog/PhabricatorCalendarImportUpdateLogType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/importlog/PhabricatorCalendarImportUpdateLogType.php
@@ -0,0 +1,38 @@
+<?php
+
+final class PhabricatorCalendarImportUpdateLogType
+ extends PhabricatorCalendarImportLogType {
+
+ const LOGTYPE = 'update';
+
+ public function getDisplayType(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ $is_new = $log->getParameter('new');
+ if ($is_new) {
+ return pht('Imported Event');
+ } else {
+ return pht('Updated Event');
+ }
+ }
+
+ public function getDisplayDescription(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ $event_phid = $log->getParameter('phid');
+ return $viewer->renderHandle($event_phid);
+ }
+
+ public function getDisplayIcon(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return 'fa-upload';
+ }
+
+ public function getDisplayColor(
+ PhabricatorUser $viewer,
+ PhabricatorCalendarImportLog $log) {
+ return 'green';
+ }
+
+}
diff --git a/src/applications/calendar/query/PhabricatorCalendarImportLogQuery.php b/src/applications/calendar/query/PhabricatorCalendarImportLogQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/query/PhabricatorCalendarImportLogQuery.php
@@ -0,0 +1,111 @@
+<?php
+
+final class PhabricatorCalendarImportLogQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $ids;
+ private $phids;
+ private $importPHIDs;
+
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
+ public function withPHIDs(array $phids) {
+ $this->phids = $phids;
+ return $this;
+ }
+
+ public function withImportPHIDs(array $phids) {
+ $this->importPHIDs = $phids;
+ return $this;
+ }
+
+ public function newResultObject() {
+ return new PhabricatorCalendarImportLog();
+ }
+
+ protected function loadPage() {
+ return $this->loadStandardPage($this->newResultObject());
+ }
+
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
+
+ if ($this->ids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'log.id IN (%Ld)',
+ $this->ids);
+ }
+
+ if ($this->phids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'log.phid IN (%Ls)',
+ $this->phids);
+ }
+
+ if ($this->importPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'log.importPHID IN (%Ls)',
+ $this->importPHIDs);
+ }
+
+
+ return $where;
+ }
+
+ protected function willFilterPage(array $page) {
+ $viewer = $this->getViewer();
+
+ $type_map = PhabricatorCalendarImportLogType::getAllLogTypes();
+ foreach ($page as $log) {
+ $type_constant = $log->getParameter('type');
+
+ $type_object = idx($type_map, $type_constant);
+ if (!$type_object) {
+ $type_object = new PhabricatorCalendarImportDefaultLogType();
+ }
+
+ $type_object = clone $type_object;
+ $log->attachLogType($type_object);
+ }
+
+ $import_phids = mpull($page, 'getImportPHID');
+
+ if ($import_phids) {
+ $imports = id(new PhabricatorCalendarImportQuery())
+ ->setViewer($viewer)
+ ->withPHIDs($import_phids)
+ ->execute();
+ $imports = mpull($imports, null, 'getPHID');
+ } else {
+ $imports = array();
+ }
+
+ foreach ($page as $key => $log) {
+ $import = idx($imports, $log->getImportPHID());
+ if (!$import) {
+ $this->didRejectResult($import);
+ unset($page[$key]);
+ continue;
+ }
+
+ $log->attachImport($import);
+ }
+
+ return $page;
+ }
+
+ protected function getPrimaryTableAlias() {
+ return 'log';
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorCalendarApplication';
+ }
+
+}
diff --git a/src/applications/calendar/storage/PhabricatorCalendarEvent.php b/src/applications/calendar/storage/PhabricatorCalendarEvent.php
--- a/src/applications/calendar/storage/PhabricatorCalendarEvent.php
+++ b/src/applications/calendar/storage/PhabricatorCalendarEvent.php
@@ -907,6 +907,10 @@
return $set;
}
+ public function isImportedEvent() {
+ return (bool)$this->getImportSourcePHID();
+ }
+
public function getImportSource() {
return $this->assertAttached($this->importSource);
}
diff --git a/src/applications/calendar/storage/PhabricatorCalendarImport.php b/src/applications/calendar/storage/PhabricatorCalendarImport.php
--- a/src/applications/calendar/storage/PhabricatorCalendarImport.php
+++ b/src/applications/calendar/storage/PhabricatorCalendarImport.php
@@ -133,6 +133,17 @@
return $timeline;
}
+ public function newLogMessage($type, array $parameters) {
+ $parameters = array(
+ 'type' => $type,
+ ) + $parameters;
+
+ return id(new PhabricatorCalendarImportLog())
+ ->setImportPHID($this->getPHID())
+ ->setParameters($parameters)
+ ->save();
+ }
+
/* -( PhabricatorDestructibleInterface )----------------------------------- */
@@ -144,12 +155,21 @@
$this->openTransaction();
$events = id(new PhabricatorCalendarEventQuery())
+ ->setViewer($viewer)
->withImportSourcePHIDs(array($this->getPHID()))
->execute();
foreach ($events as $event) {
$engine->destroyObject($event);
}
+ $logs = id(new PhabricatorCalendarImportLogQuery())
+ ->setViewer($viewer)
+ ->withImportPHIDs(array($this->getPHID()))
+ ->execute();
+ foreach ($logs as $log) {
+ $engine->destroyObject($log);
+ }
+
$this->delete();
$this->saveTransaction();
}
diff --git a/src/applications/calendar/storage/PhabricatorCalendarImportLog.php b/src/applications/calendar/storage/PhabricatorCalendarImportLog.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/storage/PhabricatorCalendarImportLog.php
@@ -0,0 +1,103 @@
+<?php
+
+final class PhabricatorCalendarImportLog
+ extends PhabricatorCalendarDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorDestructibleInterface {
+
+ protected $importPHID;
+ protected $parameters = array();
+
+ private $import = self::ATTACHABLE;
+ private $logType = self::ATTACHABLE;
+
+ protected function getConfiguration() {
+ return array(
+ self::CONFIG_SERIALIZATION => array(
+ 'parameters' => self::SERIALIZATION_JSON,
+ ),
+ self::CONFIG_KEY_SCHEMA => array(
+ 'key_import' => array(
+ 'columns' => array('importPHID'),
+ ),
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function getParameter($key, $default = null) {
+ return idx($this->parameters, $key, $default);
+ }
+
+ public function setParameter($key, $value) {
+ $this->parameters[$key] = $value;
+ return $this;
+ }
+
+ public function getImport() {
+ return $this->assertAttached($this->import);
+ }
+
+ public function attachImport(PhabricatorCalendarImport $import) {
+ $this->import = $import;
+ return $this;
+ }
+
+ public function getDisplayIcon(PhabricatorUser $viewer) {
+ return $this->getLogType()->getDisplayIcon($viewer, $this);
+ }
+
+ public function getDisplayColor(PhabricatorUser $viewer) {
+ return $this->getLogType()->getDisplayColor($viewer, $this);
+ }
+
+ public function getDisplayType(PhabricatorUser $viewer) {
+ return $this->getLogType()->getDisplayType($viewer, $this);
+ }
+
+ public function getDisplayDescription(PhabricatorUser $viewer) {
+ return $this->getLogType()->getDisplayDescription($viewer, $this);
+ }
+
+ public function getLogType() {
+ return $this->assertAttached($this->logType);
+ }
+
+ public function attachLogType(PhabricatorCalendarImportLogType $type) {
+ $this->logType = $type;
+ return $this;
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ );
+ }
+
+ public function getPolicy($capability) {
+ return PhabricatorPolicies::getMostOpenPolicy();
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return null;
+ }
+
+
+/* -( PhabricatorDestructibleInterface )----------------------------------- */
+
+
+ public function destroyObjectPermanently(
+ PhabricatorDestructionEngine $engine) {
+ $viewer = $engine->getViewer();
+ $this->delete();
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Thu, Oct 24, 6:16 AM (2 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6741989
Default Alt Text
D16704.id40215.diff (29 KB)

Event Timeline