@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add import log messages to Calendar imports

Summary: Ref T10747. When stuff goes wrong (or right) let the user know what happened.

Test Plan: {F1870139}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10747

Differential Revision: https://secure.phabricator.com/D16704

+643 -8
+8
resources/sql/autopatches/20161013.cal.01.importlog.sql
··· 1 + CREATE TABLE {$NAMESPACE}_calendar.calendar_importlog ( 2 + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 + importPHID VARBINARY(64) NOT NULL, 4 + parameters LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}, 5 + dateCreated INT UNSIGNED NOT NULL, 6 + dateModified INT UNSIGNED NOT NULL, 7 + KEY `key_import` (`importPHID`) 8 + ) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
+24
src/__phutil_library_map__.php
··· 2104 2104 'PhabricatorCalendarICSWriter' => 'applications/calendar/util/PhabricatorCalendarICSWriter.php', 2105 2105 'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php', 2106 2106 'PhabricatorCalendarImport' => 'applications/calendar/storage/PhabricatorCalendarImport.php', 2107 + 'PhabricatorCalendarImportDefaultLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportDefaultLogType.php', 2107 2108 'PhabricatorCalendarImportDisableController' => 'applications/calendar/controller/PhabricatorCalendarImportDisableController.php', 2108 2109 'PhabricatorCalendarImportDisableTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportDisableTransaction.php', 2110 + 'PhabricatorCalendarImportDuplicateLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportDuplicateLogType.php', 2109 2111 'PhabricatorCalendarImportEditController' => 'applications/calendar/controller/PhabricatorCalendarImportEditController.php', 2110 2112 'PhabricatorCalendarImportEditEngine' => 'applications/calendar/editor/PhabricatorCalendarImportEditEngine.php', 2111 2113 'PhabricatorCalendarImportEditor' => 'applications/calendar/editor/PhabricatorCalendarImportEditor.php', 2114 + 'PhabricatorCalendarImportEmptyLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportEmptyLogType.php', 2112 2115 'PhabricatorCalendarImportEngine' => 'applications/calendar/import/PhabricatorCalendarImportEngine.php', 2113 2116 'PhabricatorCalendarImportICSFileTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportICSFileTransaction.php', 2117 + 'PhabricatorCalendarImportIgnoredNodeLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportIgnoredNodeLogType.php', 2114 2118 'PhabricatorCalendarImportListController' => 'applications/calendar/controller/PhabricatorCalendarImportListController.php', 2119 + 'PhabricatorCalendarImportLog' => 'applications/calendar/storage/PhabricatorCalendarImportLog.php', 2120 + 'PhabricatorCalendarImportLogQuery' => 'applications/calendar/query/PhabricatorCalendarImportLogQuery.php', 2121 + 'PhabricatorCalendarImportLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportLogType.php', 2115 2122 'PhabricatorCalendarImportNameTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportNameTransaction.php', 2123 + 'PhabricatorCalendarImportOriginalLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportOriginalLogType.php', 2124 + 'PhabricatorCalendarImportOrphanLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportOrphanLogType.php', 2116 2125 'PhabricatorCalendarImportPHIDType' => 'applications/calendar/phid/PhabricatorCalendarImportPHIDType.php', 2117 2126 'PhabricatorCalendarImportQuery' => 'applications/calendar/query/PhabricatorCalendarImportQuery.php', 2118 2127 'PhabricatorCalendarImportSearchEngine' => 'applications/calendar/query/PhabricatorCalendarImportSearchEngine.php', 2119 2128 'PhabricatorCalendarImportTransaction' => 'applications/calendar/storage/PhabricatorCalendarImportTransaction.php', 2120 2129 'PhabricatorCalendarImportTransactionQuery' => 'applications/calendar/query/PhabricatorCalendarImportTransactionQuery.php', 2121 2130 'PhabricatorCalendarImportTransactionType' => 'applications/calendar/xaction/PhabricatorCalendarImportTransactionType.php', 2131 + 'PhabricatorCalendarImportUpdateLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportUpdateLogType.php', 2122 2132 'PhabricatorCalendarImportViewController' => 'applications/calendar/controller/PhabricatorCalendarImportViewController.php', 2123 2133 'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php', 2124 2134 'PhabricatorCalendarReplyHandler' => 'applications/calendar/mail/PhabricatorCalendarReplyHandler.php', ··· 6921 6931 'PhabricatorApplicationTransactionInterface', 6922 6932 'PhabricatorDestructibleInterface', 6923 6933 ), 6934 + 'PhabricatorCalendarImportDefaultLogType' => 'PhabricatorCalendarImportLogType', 6924 6935 'PhabricatorCalendarImportDisableController' => 'PhabricatorCalendarController', 6925 6936 'PhabricatorCalendarImportDisableTransaction' => 'PhabricatorCalendarImportTransactionType', 6937 + 'PhabricatorCalendarImportDuplicateLogType' => 'PhabricatorCalendarImportLogType', 6926 6938 'PhabricatorCalendarImportEditController' => 'PhabricatorCalendarController', 6927 6939 'PhabricatorCalendarImportEditEngine' => 'PhabricatorEditEngine', 6928 6940 'PhabricatorCalendarImportEditor' => 'PhabricatorApplicationTransactionEditor', 6941 + 'PhabricatorCalendarImportEmptyLogType' => 'PhabricatorCalendarImportLogType', 6929 6942 'PhabricatorCalendarImportEngine' => 'Phobject', 6930 6943 'PhabricatorCalendarImportICSFileTransaction' => 'PhabricatorCalendarImportTransactionType', 6944 + 'PhabricatorCalendarImportIgnoredNodeLogType' => 'PhabricatorCalendarImportLogType', 6931 6945 'PhabricatorCalendarImportListController' => 'PhabricatorCalendarController', 6946 + 'PhabricatorCalendarImportLog' => array( 6947 + 'PhabricatorCalendarDAO', 6948 + 'PhabricatorPolicyInterface', 6949 + 'PhabricatorDestructibleInterface', 6950 + ), 6951 + 'PhabricatorCalendarImportLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 6952 + 'PhabricatorCalendarImportLogType' => 'Phobject', 6932 6953 'PhabricatorCalendarImportNameTransaction' => 'PhabricatorCalendarImportTransactionType', 6954 + 'PhabricatorCalendarImportOriginalLogType' => 'PhabricatorCalendarImportLogType', 6955 + 'PhabricatorCalendarImportOrphanLogType' => 'PhabricatorCalendarImportLogType', 6933 6956 'PhabricatorCalendarImportPHIDType' => 'PhabricatorPHIDType', 6934 6957 'PhabricatorCalendarImportQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 6935 6958 'PhabricatorCalendarImportSearchEngine' => 'PhabricatorApplicationSearchEngine', 6936 6959 'PhabricatorCalendarImportTransaction' => 'PhabricatorModularTransaction', 6937 6960 'PhabricatorCalendarImportTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 6938 6961 'PhabricatorCalendarImportTransactionType' => 'PhabricatorModularTransactionType', 6962 + 'PhabricatorCalendarImportUpdateLogType' => 'PhabricatorCalendarImportLogType', 6939 6963 'PhabricatorCalendarImportViewController' => 'PhabricatorCalendarController', 6940 6964 'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule', 6941 6965 'PhabricatorCalendarReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
+66 -2
src/applications/calendar/controller/PhabricatorCalendarImportViewController.php
··· 30 30 $curtain = $this->buildCurtain($import); 31 31 $details = $this->buildPropertySection($import); 32 32 33 + $log_messages = $this->buildLogMessages($import); 33 34 $imported_events = $this->buildImportedEvents($import); 34 35 35 36 $view = id(new PHUITwoColumnView()) 36 37 ->setHeader($header) 37 38 ->setMainColumn( 38 39 array( 40 + $log_messages, 39 41 $imported_events, 40 42 $timeline, 41 43 )) ··· 134 136 return $properties; 135 137 } 136 138 137 - private function buildImportedEvents( 138 - PhabricatorCalendarImport $import) { 139 + private function buildLogMessages(PhabricatorCalendarImport $import) { 140 + $viewer = $this->getViewer(); 141 + 142 + $logs = id(new PhabricatorCalendarImportLogQuery()) 143 + ->setViewer($viewer) 144 + ->withImportPHIDs(array($import->getPHID())) 145 + ->setLimit(25) 146 + ->execute(); 147 + 148 + $rows = array(); 149 + foreach ($logs as $log) { 150 + $icon = $log->getDisplayIcon($viewer); 151 + $color = $log->getDisplayColor($viewer); 152 + $name = $log->getDisplayType($viewer); 153 + $description = $log->getDisplayDescription($viewer); 154 + 155 + $rows[] = array( 156 + $log->getID(), 157 + id(new PHUIIconView())->setIcon($icon, $color), 158 + $name, 159 + $description, 160 + phabricator_datetime($log->getDateCreated(), $viewer), 161 + ); 162 + } 163 + 164 + $table = id(new AphrontTableView($rows)) 165 + ->setHeaders( 166 + array( 167 + pht('ID'), 168 + null, 169 + pht('Type'), 170 + pht('Mesage'), 171 + pht('Date'), 172 + )) 173 + ->setColumnClasses( 174 + array( 175 + null, 176 + null, 177 + 'pri', 178 + 'wide', 179 + null, 180 + )); 181 + 182 + $all_uri = $this->getApplicationURI('import/log/'); 183 + $all_uri = (string)id(new PhutilURI($all_uri)) 184 + ->setQueryParam('importSourcePHID', $import->getPHID()); 185 + 186 + $all_button = id(new PHUIButtonView()) 187 + ->setTag('a') 188 + ->setText(pht('View All')) 189 + ->setIcon('fa-search') 190 + ->setHref($all_uri); 191 + 192 + $header = id(new PHUIHeaderView()) 193 + ->setHeader(pht('Log Messages')) 194 + ->addActionLink($all_button); 195 + 196 + return id(new PHUIObjectBoxView()) 197 + ->setHeader($header) 198 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 199 + ->setTable($table); 200 + } 201 + 202 + private function buildImportedEvents(PhabricatorCalendarImport $import) { 139 203 $viewer = $this->getViewer(); 140 204 141 205 $engine = id(new PhabricatorCalendarEventSearchEngine())
+81 -6
src/applications/calendar/import/PhabricatorCalendarImportEngine.php
··· 49 49 $nodes = array(); 50 50 foreach ($root->getChildren() as $document) { 51 51 foreach ($document->getChildren() as $node) { 52 - if ($node->getNodeType() != $event_type) { 53 - // TODO: Warn that we ignored this. 52 + $node_type = $node->getNodeType(); 53 + if ($node_type != $event_type) { 54 + $import->newLogMessage( 55 + PhabricatorCalendarImportIgnoredNodeLogType::LOGTYPE, 56 + array( 57 + 'node.type' => $node_type, 58 + )); 54 59 continue; 55 60 } 56 61 ··· 59 64 } 60 65 61 66 $node_map = array(); 62 - $parent_uids = array(); 63 67 foreach ($nodes as $node) { 64 68 $full_uid = $this->getFullNodeUID($node); 65 69 if (isset($node_map[$full_uid])) { 66 - // TODO: Warn that we got a duplicate. 70 + $import->newLogMessage( 71 + PhabricatorCalendarImportDuplicateLogType::LOGTYPE, 72 + array( 73 + 'uid.full' => $full_uid, 74 + )); 67 75 continue; 68 76 } 69 77 $node_map[$full_uid] = $node; 70 78 } 71 79 80 + // If we already know about some of these events and they were created 81 + // here, we're not going to import it again. This can happen if a user 82 + // exports an event and then tries to import it again. This is probably 83 + // not what they meant to do and this pathway generally leads to madness. 84 + $likely_phids = array(); 85 + foreach ($node_map as $full_uid => $node) { 86 + $uid = $node->getUID(); 87 + $matches = null; 88 + if (preg_match('/^(PHID-.*)@(.*)\z/', $uid, $matches)) { 89 + $likely_phids[$full_uid] = $matches[1]; 90 + } 91 + } 92 + 93 + if ($likely_phids) { 94 + // NOTE: We're using the omnipotent viewer here because we don't want 95 + // to collide with events that already exist, even if you can't see 96 + // them. 97 + $events = id(new PhabricatorCalendarEventQuery()) 98 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 99 + ->withPHIDs($likely_phids) 100 + ->execute(); 101 + $events = mpull($events, null, 'getPHID'); 102 + foreach ($node_map as $full_uid => $node) { 103 + $phid = idx($likely_phids, $full_uid); 104 + if (!$phid) { 105 + continue; 106 + } 107 + 108 + $event = idx($events, $phid); 109 + if (!$event) { 110 + continue; 111 + } 112 + 113 + $import->newLogMessage( 114 + PhabricatorCalendarImportOriginalLogType::LOGTYPE, 115 + array( 116 + 'phid' => $event->getPHID(), 117 + )); 118 + 119 + unset($node_map[$full_uid]); 120 + } 121 + } 122 + 72 123 if ($node_map) { 73 124 $events = id(new PhabricatorCalendarEventQuery()) 74 125 ->setViewer($viewer) ··· 114 165 // does not exist or we're going to delete it anyway. We just drop 115 166 // this node. 116 167 117 - // TODO: Warn that we got rid of an event with no parent. 168 + $import->newLogMessage( 169 + PhabricatorCalendarImportOrphanLogType::LOGTYPE, 170 + array( 171 + 'uid.full' => $full_uid, 172 + 'uid.parent' => $parent_uid, 173 + )); 118 174 119 175 continue; 120 176 } ··· 130 186 $content_source = PhabricatorContentSource::newForSource( 131 187 PhabricatorWebContentSource::SOURCECONST); 132 188 189 + // NOTE: We're using the omnipotent user here because imported events are 190 + // otherwise immutable. 191 + $edit_actor = PhabricatorUser::getOmnipotentUser(); 192 + 133 193 $update_map = array_select_keys($update_map, $insert_order); 134 194 foreach ($update_map as $full_uid => $event) { 135 195 $parent_uid = $this->getParentNodeUID($node_map[$full_uid]); ··· 144 204 $event_xactions = $xactions[$full_uid]; 145 205 146 206 $editor = id(new PhabricatorCalendarEventEditor()) 147 - ->setActor($viewer) 207 + ->setActor($edit_actor) 148 208 ->setActingAsPHID($import->getPHID()) 149 209 ->setContentSource($content_source) 150 210 ->setContinueOnNoEffect(true) 151 211 ->setContinueOnMissingFields(true); 152 212 213 + $is_new = !$event->getID(); 214 + 153 215 $editor->applyTransactions($event, $event_xactions); 216 + 217 + $import->newLogMessage( 218 + PhabricatorCalendarImportUpdateLogType::LOGTYPE, 219 + array( 220 + 'new' => $is_new, 221 + 'phid' => $event->getPHID(), 222 + )); 223 + } 224 + 225 + if (!$update_map) { 226 + $import->newLogMessage( 227 + PhabricatorCalendarImportEmptyLogType::LOGTYPE, 228 + array()); 154 229 } 155 230 156 231 // TODO: When the source is a subscription-based ICS file or some other
+20
src/applications/calendar/importlog/PhabricatorCalendarImportDefaultLogType.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarImportDefaultLogType 4 + extends PhabricatorCalendarImportLogType { 5 + 6 + const LOGTYPE = 'default'; 7 + 8 + public function getDisplayType( 9 + PhabricatorUser $viewer, 10 + PhabricatorCalendarImportLog $log) { 11 + 12 + $type = $log->getParameter('type'); 13 + if (strlen($type)) { 14 + return pht('Unknown Message "%s"', $type); 15 + } else { 16 + return pht('Unknown Message'); 17 + } 18 + } 19 + 20 + }
+23
src/applications/calendar/importlog/PhabricatorCalendarImportDuplicateLogType.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarImportDuplicateLogType 4 + extends PhabricatorCalendarImportLogType { 5 + 6 + const LOGTYPE = 'duplicate'; 7 + 8 + public function getDisplayType( 9 + PhabricatorUser $viewer, 10 + PhabricatorCalendarImportLog $log) { 11 + return pht('Duplicate Event'); 12 + } 13 + 14 + public function getDisplayDescription( 15 + PhabricatorUser $viewer, 16 + PhabricatorCalendarImportLog $log) { 17 + $duplicate_uid = $log->getParameter('uid.full'); 18 + return pht( 19 + 'Ignored duplicate event "%s" present in source.', 20 + $duplicate_uid); 21 + } 22 + 23 + }
+32
src/applications/calendar/importlog/PhabricatorCalendarImportEmptyLogType.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarImportEmptyLogType 4 + extends PhabricatorCalendarImportLogType { 5 + 6 + const LOGTYPE = 'empty'; 7 + 8 + public function getDisplayType( 9 + PhabricatorUser $viewer, 10 + PhabricatorCalendarImportLog $log) { 11 + return pht('No Events Imported'); 12 + } 13 + 14 + public function getDisplayDescription( 15 + PhabricatorUser $viewer, 16 + PhabricatorCalendarImportLog $log) { 17 + return pht('Found no valid events to import.'); 18 + } 19 + 20 + public function getDisplayIcon( 21 + PhabricatorUser $viewer, 22 + PhabricatorCalendarImportLog $log) { 23 + return 'fa-ban'; 24 + } 25 + 26 + public function getDisplayColor( 27 + PhabricatorUser $viewer, 28 + PhabricatorCalendarImportLog $log) { 29 + return 'red'; 30 + } 31 + 32 + }
+23
src/applications/calendar/importlog/PhabricatorCalendarImportIgnoredNodeLogType.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarImportIgnoredNodeLogType 4 + extends PhabricatorCalendarImportLogType { 5 + 6 + const LOGTYPE = 'nodetype'; 7 + 8 + public function getDisplayType( 9 + PhabricatorUser $viewer, 10 + PhabricatorCalendarImportLog $log) { 11 + return pht('Ignored Node'); 12 + } 13 + 14 + public function getDisplayDescription( 15 + PhabricatorUser $viewer, 16 + PhabricatorCalendarImportLog $log) { 17 + $node_type = $log->getParameter('node.type'); 18 + return pht( 19 + 'Ignored unsupported "%s" node present in source.', 20 + $node_type); 21 + } 22 + 23 + }
+39
src/applications/calendar/importlog/PhabricatorCalendarImportLogType.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorCalendarImportLogType 4 + extends Phobject { 5 + 6 + final public function getLogTypeConstant() { 7 + return $this->getPhobjectClassConstant('LOGTYPE', 64); 8 + } 9 + 10 + final public static function getAllLogTypes() { 11 + return id(new PhutilClassMapQuery()) 12 + ->setAncestorClass(__CLASS__) 13 + ->setUniqueMethod('getLogTypeConstant') 14 + ->execute(); 15 + } 16 + 17 + abstract public function getDisplayType( 18 + PhabricatorUser $viewer, 19 + PhabricatorCalendarImportLog $log); 20 + 21 + public function getDisplayIcon( 22 + PhabricatorUser $viewer, 23 + PhabricatorCalendarImportLog $log) { 24 + return 'fa-warning'; 25 + } 26 + 27 + public function getDisplayColor( 28 + PhabricatorUser $viewer, 29 + PhabricatorCalendarImportLog $log) { 30 + return 'yellow'; 31 + } 32 + 33 + public function getDisplayDescription( 34 + PhabricatorUser $viewer, 35 + PhabricatorCalendarImportLog $log) { 36 + return null; 37 + } 38 + 39 + }
+26
src/applications/calendar/importlog/PhabricatorCalendarImportOriginalLogType.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarImportOriginalLogType 4 + extends PhabricatorCalendarImportLogType { 5 + 6 + const LOGTYPE = 'original'; 7 + 8 + public function getDisplayType( 9 + PhabricatorUser $viewer, 10 + PhabricatorCalendarImportLog $log) { 11 + return pht('Original Event'); 12 + } 13 + 14 + public function getDisplayDescription( 15 + PhabricatorUser $viewer, 16 + PhabricatorCalendarImportLog $log) { 17 + 18 + $phid = $log->getParameter('phid'); 19 + 20 + return pht( 21 + 'Ignored an event (%s) because the original version of this event '. 22 + 'was created here.', 23 + $viewer->renderHandle($phid)); 24 + } 25 + 26 + }
+25
src/applications/calendar/importlog/PhabricatorCalendarImportOrphanLogType.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarImportOrphanLogType 4 + extends PhabricatorCalendarImportLogType { 5 + 6 + const LOGTYPE = 'orphan'; 7 + 8 + public function getDisplayType( 9 + PhabricatorUser $viewer, 10 + PhabricatorCalendarImportLog $log) { 11 + return pht('Orphan'); 12 + } 13 + 14 + public function getDisplayDescription( 15 + PhabricatorUser $viewer, 16 + PhabricatorCalendarImportLog $log) { 17 + $child_uid = $log->getParameter('uid.full'); 18 + $parent_uid = $log->getParameter('uid.parent'); 19 + return pht( 20 + 'Found orphaned child event ("%s") without a parent event ("%s").', 21 + $child_uid, 22 + $parent_uid); 23 + } 24 + 25 + }
+38
src/applications/calendar/importlog/PhabricatorCalendarImportUpdateLogType.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarImportUpdateLogType 4 + extends PhabricatorCalendarImportLogType { 5 + 6 + const LOGTYPE = 'update'; 7 + 8 + public function getDisplayType( 9 + PhabricatorUser $viewer, 10 + PhabricatorCalendarImportLog $log) { 11 + $is_new = $log->getParameter('new'); 12 + if ($is_new) { 13 + return pht('Imported Event'); 14 + } else { 15 + return pht('Updated Event'); 16 + } 17 + } 18 + 19 + public function getDisplayDescription( 20 + PhabricatorUser $viewer, 21 + PhabricatorCalendarImportLog $log) { 22 + $event_phid = $log->getParameter('phid'); 23 + return $viewer->renderHandle($event_phid); 24 + } 25 + 26 + public function getDisplayIcon( 27 + PhabricatorUser $viewer, 28 + PhabricatorCalendarImportLog $log) { 29 + return 'fa-upload'; 30 + } 31 + 32 + public function getDisplayColor( 33 + PhabricatorUser $viewer, 34 + PhabricatorCalendarImportLog $log) { 35 + return 'green'; 36 + } 37 + 38 + }
+111
src/applications/calendar/query/PhabricatorCalendarImportLogQuery.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarImportLogQuery 4 + extends PhabricatorCursorPagedPolicyAwareQuery { 5 + 6 + private $ids; 7 + private $phids; 8 + private $importPHIDs; 9 + 10 + public function withIDs(array $ids) { 11 + $this->ids = $ids; 12 + return $this; 13 + } 14 + 15 + public function withPHIDs(array $phids) { 16 + $this->phids = $phids; 17 + return $this; 18 + } 19 + 20 + public function withImportPHIDs(array $phids) { 21 + $this->importPHIDs = $phids; 22 + return $this; 23 + } 24 + 25 + public function newResultObject() { 26 + return new PhabricatorCalendarImportLog(); 27 + } 28 + 29 + protected function loadPage() { 30 + return $this->loadStandardPage($this->newResultObject()); 31 + } 32 + 33 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 34 + $where = parent::buildWhereClauseParts($conn); 35 + 36 + if ($this->ids !== null) { 37 + $where[] = qsprintf( 38 + $conn, 39 + 'log.id IN (%Ld)', 40 + $this->ids); 41 + } 42 + 43 + if ($this->phids !== null) { 44 + $where[] = qsprintf( 45 + $conn, 46 + 'log.phid IN (%Ls)', 47 + $this->phids); 48 + } 49 + 50 + if ($this->importPHIDs !== null) { 51 + $where[] = qsprintf( 52 + $conn, 53 + 'log.importPHID IN (%Ls)', 54 + $this->importPHIDs); 55 + } 56 + 57 + 58 + return $where; 59 + } 60 + 61 + protected function willFilterPage(array $page) { 62 + $viewer = $this->getViewer(); 63 + 64 + $type_map = PhabricatorCalendarImportLogType::getAllLogTypes(); 65 + foreach ($page as $log) { 66 + $type_constant = $log->getParameter('type'); 67 + 68 + $type_object = idx($type_map, $type_constant); 69 + if (!$type_object) { 70 + $type_object = new PhabricatorCalendarImportDefaultLogType(); 71 + } 72 + 73 + $type_object = clone $type_object; 74 + $log->attachLogType($type_object); 75 + } 76 + 77 + $import_phids = mpull($page, 'getImportPHID'); 78 + 79 + if ($import_phids) { 80 + $imports = id(new PhabricatorCalendarImportQuery()) 81 + ->setViewer($viewer) 82 + ->withPHIDs($import_phids) 83 + ->execute(); 84 + $imports = mpull($imports, null, 'getPHID'); 85 + } else { 86 + $imports = array(); 87 + } 88 + 89 + foreach ($page as $key => $log) { 90 + $import = idx($imports, $log->getImportPHID()); 91 + if (!$import) { 92 + $this->didRejectResult($import); 93 + unset($page[$key]); 94 + continue; 95 + } 96 + 97 + $log->attachImport($import); 98 + } 99 + 100 + return $page; 101 + } 102 + 103 + protected function getPrimaryTableAlias() { 104 + return 'log'; 105 + } 106 + 107 + public function getQueryApplicationClass() { 108 + return 'PhabricatorCalendarApplication'; 109 + } 110 + 111 + }
+4
src/applications/calendar/storage/PhabricatorCalendarEvent.php
··· 907 907 return $set; 908 908 } 909 909 910 + public function isImportedEvent() { 911 + return (bool)$this->getImportSourcePHID(); 912 + } 913 + 910 914 public function getImportSource() { 911 915 return $this->assertAttached($this->importSource); 912 916 }
+20
src/applications/calendar/storage/PhabricatorCalendarImport.php
··· 133 133 return $timeline; 134 134 } 135 135 136 + public function newLogMessage($type, array $parameters) { 137 + $parameters = array( 138 + 'type' => $type, 139 + ) + $parameters; 140 + 141 + return id(new PhabricatorCalendarImportLog()) 142 + ->setImportPHID($this->getPHID()) 143 + ->setParameters($parameters) 144 + ->save(); 145 + } 146 + 136 147 137 148 /* -( PhabricatorDestructibleInterface )----------------------------------- */ 138 149 ··· 144 155 $this->openTransaction(); 145 156 146 157 $events = id(new PhabricatorCalendarEventQuery()) 158 + ->setViewer($viewer) 147 159 ->withImportSourcePHIDs(array($this->getPHID())) 148 160 ->execute(); 149 161 foreach ($events as $event) { 150 162 $engine->destroyObject($event); 163 + } 164 + 165 + $logs = id(new PhabricatorCalendarImportLogQuery()) 166 + ->setViewer($viewer) 167 + ->withImportPHIDs(array($this->getPHID())) 168 + ->execute(); 169 + foreach ($logs as $log) { 170 + $engine->destroyObject($log); 151 171 } 152 172 153 173 $this->delete();
+103
src/applications/calendar/storage/PhabricatorCalendarImportLog.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarImportLog 4 + extends PhabricatorCalendarDAO 5 + implements 6 + PhabricatorPolicyInterface, 7 + PhabricatorDestructibleInterface { 8 + 9 + protected $importPHID; 10 + protected $parameters = array(); 11 + 12 + private $import = self::ATTACHABLE; 13 + private $logType = self::ATTACHABLE; 14 + 15 + protected function getConfiguration() { 16 + return array( 17 + self::CONFIG_SERIALIZATION => array( 18 + 'parameters' => self::SERIALIZATION_JSON, 19 + ), 20 + self::CONFIG_KEY_SCHEMA => array( 21 + 'key_import' => array( 22 + 'columns' => array('importPHID'), 23 + ), 24 + ), 25 + ) + parent::getConfiguration(); 26 + } 27 + 28 + public function getParameter($key, $default = null) { 29 + return idx($this->parameters, $key, $default); 30 + } 31 + 32 + public function setParameter($key, $value) { 33 + $this->parameters[$key] = $value; 34 + return $this; 35 + } 36 + 37 + public function getImport() { 38 + return $this->assertAttached($this->import); 39 + } 40 + 41 + public function attachImport(PhabricatorCalendarImport $import) { 42 + $this->import = $import; 43 + return $this; 44 + } 45 + 46 + public function getDisplayIcon(PhabricatorUser $viewer) { 47 + return $this->getLogType()->getDisplayIcon($viewer, $this); 48 + } 49 + 50 + public function getDisplayColor(PhabricatorUser $viewer) { 51 + return $this->getLogType()->getDisplayColor($viewer, $this); 52 + } 53 + 54 + public function getDisplayType(PhabricatorUser $viewer) { 55 + return $this->getLogType()->getDisplayType($viewer, $this); 56 + } 57 + 58 + public function getDisplayDescription(PhabricatorUser $viewer) { 59 + return $this->getLogType()->getDisplayDescription($viewer, $this); 60 + } 61 + 62 + public function getLogType() { 63 + return $this->assertAttached($this->logType); 64 + } 65 + 66 + public function attachLogType(PhabricatorCalendarImportLogType $type) { 67 + $this->logType = $type; 68 + return $this; 69 + } 70 + 71 + 72 + /* -( PhabricatorPolicyInterface )----------------------------------------- */ 73 + 74 + 75 + public function getCapabilities() { 76 + return array( 77 + PhabricatorPolicyCapability::CAN_VIEW, 78 + ); 79 + } 80 + 81 + public function getPolicy($capability) { 82 + return PhabricatorPolicies::getMostOpenPolicy(); 83 + } 84 + 85 + public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 86 + return false; 87 + } 88 + 89 + public function describeAutomaticCapability($capability) { 90 + return null; 91 + } 92 + 93 + 94 + /* -( PhabricatorDestructibleInterface )----------------------------------- */ 95 + 96 + 97 + public function destroyObjectPermanently( 98 + PhabricatorDestructionEngine $engine) { 99 + $viewer = $engine->getViewer(); 100 + $this->delete(); 101 + } 102 + 103 + }