Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13989270
D16704.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
29 KB
Referenced Files
None
Subscribers
None
D16704.id.diff
View Options
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
@@ -2104,21 +2104,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',
@@ -6921,21 +6931,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
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 22, 7:25 PM (3 w, 5 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6731560
Default Alt Text
D16704.id.diff (29 KB)
Attached To
Mode
D16704: Add import log messages to Calendar imports
Attached
Detach File
Event Timeline
Log In to Comment