diff --git a/resources/sql/patches/20130820.file-mailkey-populate.php b/resources/sql/patches/20130820.file-mailkey-populate.php new file mode 100644 index 0000000000..f1d2a22a92 --- /dev/null +++ b/resources/sql/patches/20130820.file-mailkey-populate.php @@ -0,0 +1,32 @@ +getTableName(); + +$conn_w = $table->establishConnection('w'); +$conn_w->openTransaction(); + +$sql = array(); +foreach (new LiskRawMigrationIterator($conn_w, 'file') as $row) { + $sql[] = qsprintf( + $conn_w, + '(%d, %s)', + $row['id'], + Filesystem::readRandomCharacters(20)); +} + +if ($sql) { + foreach (PhabricatorLiskDAO::chunkSQL($sql, ', ') as $chunk) { + queryfx( + $conn_w, + 'INSERT INTO %T (id, mailKey) VALUES %Q '. + 'ON DUPLICATE KEY UPDATE mailKey = VALUES(mailKey)', + $table_name, + $chunk); + } +} + +$table->saveTransaction(); +echo "Done.\n"; diff --git a/resources/sql/patches/20130820.filemailkey.sql b/resources/sql/patches/20130820.filemailkey.sql new file mode 100644 index 0000000000..7daa46a609 --- /dev/null +++ b/resources/sql/patches/20130820.filemailkey.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_file.file + ADD `mailKey` varchar(20) NOT NULL; diff --git a/resources/sql/patches/20130820.filexactions.sql b/resources/sql/patches/20130820.filexactions.sql new file mode 100644 index 0000000000..8f92df563f --- /dev/null +++ b/resources/sql/patches/20130820.filexactions.sql @@ -0,0 +1,42 @@ +CREATE TABLE {$NAMESPACE}_file.file_transaction ( + id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + phid VARCHAR(64) NOT NULL COLLATE utf8_bin, + authorPHID VARCHAR(64) NOT NULL COLLATE utf8_bin, + objectPHID VARCHAR(64) NOT NULL COLLATE utf8_bin, + viewPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin, + editPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin, + commentPHID VARCHAR(64) COLLATE utf8_bin, + commentVersion INT UNSIGNED NOT NULL, + transactionType VARCHAR(32) NOT NULL COLLATE utf8_bin, + oldValue LONGTEXT NOT NULL COLLATE utf8_bin, + newValue LONGTEXT NOT NULL COLLATE utf8_bin, + contentSource LONGTEXT NOT NULL COLLATE utf8_bin, + metadata LONGTEXT NOT NULL COLLATE utf8_bin, + dateCreated INT UNSIGNED NOT NULL, + dateModified INT UNSIGNED NOT NULL, + + UNIQUE KEY `key_phid` (phid), + KEY `key_object` (objectPHID) + +) ENGINE=InnoDB, COLLATE utf8_general_ci; + +CREATE TABLE {$NAMESPACE}_file.file_transaction_comment ( + id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + phid VARCHAR(64) NOT NULL COLLATE utf8_bin, + transactionPHID VARCHAR(64) COLLATE utf8_bin, + authorPHID VARCHAR(64) NOT NULL COLLATE utf8_bin, + viewPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin, + editPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin, + commentVersion INT UNSIGNED NOT NULL, + content LONGTEXT NOT NULL COLLATE utf8_bin, + contentSource LONGTEXT NOT NULL COLLATE utf8_bin, + isDeleted BOOL NOT NULL, + dateCreated INT UNSIGNED NOT NULL, + dateModified INT UNSIGNED NOT NULL, + + UNIQUE KEY `key_phid` (phid), + UNIQUE KEY `key_version` (transactionPHID, commentVersion), + UNIQUE KEY `key_draft` (authorPHID, transactionPHID) + +) ENGINE=InnoDB, COLLATE utf8_general_ci; + diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 2284ced051..93e390d07d 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -596,7 +596,9 @@ phutil_register_library_map(array( 'FeedPublisherHTTPWorker' => 'applications/feed/worker/FeedPublisherHTTPWorker.php', 'FeedPublisherWorker' => 'applications/feed/worker/FeedPublisherWorker.php', 'FeedPushWorker' => 'applications/feed/worker/FeedPushWorker.php', - 'FilesCreateMailReceiver' => 'applications/files/mail/FilesCreateMailReceiver.php', + 'FileCreateMailReceiver' => 'applications/files/mail/FileCreateMailReceiver.php', + 'FileMailReceiver' => 'applications/files/mail/FileMailReceiver.php', + 'FileReplyHandler' => 'applications/files/mail/FileReplyHandler.php', 'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php', 'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php', 'HarbormasterRunnerWorker' => 'applications/harbormaster/worker/HarbormasterRunnerWorker.php', @@ -1161,11 +1163,13 @@ phutil_register_library_map(array( 'PhabricatorFeedStoryStatus' => 'applications/feed/story/PhabricatorFeedStoryStatus.php', 'PhabricatorFeedStoryTypeConstants' => 'applications/feed/constants/PhabricatorFeedStoryTypeConstants.php', 'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.php', + 'PhabricatorFileCommentController' => 'applications/files/controller/PhabricatorFileCommentController.php', 'PhabricatorFileController' => 'applications/files/controller/PhabricatorFileController.php', 'PhabricatorFileDAO' => 'applications/files/storage/PhabricatorFileDAO.php', 'PhabricatorFileDataController' => 'applications/files/controller/PhabricatorFileDataController.php', 'PhabricatorFileDeleteController' => 'applications/files/controller/PhabricatorFileDeleteController.php', 'PhabricatorFileDropUploadController' => 'applications/files/controller/PhabricatorFileDropUploadController.php', + 'PhabricatorFileEditor' => 'applications/files/editor/PhabricatorFileEditor.php', 'PhabricatorFileImageMacro' => 'applications/macro/storage/PhabricatorFileImageMacro.php', 'PhabricatorFileInfoController' => 'applications/files/controller/PhabricatorFileInfoController.php', 'PhabricatorFileLinkListView' => 'view/layout/PhabricatorFileLinkListView.php', @@ -1181,6 +1185,9 @@ phutil_register_library_map(array( 'PhabricatorFileStorageEngineSelector' => 'applications/files/engineselector/PhabricatorFileStorageEngineSelector.php', 'PhabricatorFileTestCase' => 'applications/files/storage/__tests__/PhabricatorFileTestCase.php', 'PhabricatorFileTestDataGenerator' => 'applications/files/lipsum/PhabricatorFileTestDataGenerator.php', + 'PhabricatorFileTransaction' => 'applications/files/storage/PhabricatorFileTransaction.php', + 'PhabricatorFileTransactionComment' => 'applications/files/storage/PhabricatorFileTransactionComment.php', + 'PhabricatorFileTransactionQuery' => 'applications/files/query/PhabricatorFileTransactionQuery.php', 'PhabricatorFileTransformController' => 'applications/files/controller/PhabricatorFileTransformController.php', 'PhabricatorFileUploadController' => 'applications/files/controller/PhabricatorFileUploadController.php', 'PhabricatorFileUploadDialogController' => 'applications/files/controller/PhabricatorFileUploadDialogController.php', @@ -2631,7 +2638,9 @@ phutil_register_library_map(array( 'FeedPublisherHTTPWorker' => 'FeedPushWorker', 'FeedPublisherWorker' => 'FeedPushWorker', 'FeedPushWorker' => 'PhabricatorWorker', - 'FilesCreateMailReceiver' => 'PhabricatorMailReceiver', + 'FileCreateMailReceiver' => 'PhabricatorMailReceiver', + 'FileMailReceiver' => 'PhabricatorObjectMailReceiver', + 'FileReplyHandler' => 'PhabricatorMailReplyHandler', 'HarbormasterDAO' => 'PhabricatorLiskDAO', 'HarbormasterObject' => 'HarbormasterDAO', 'HarbormasterRunnerWorker' => 'PhabricatorWorker', @@ -3245,13 +3254,17 @@ phutil_register_library_map(array( 'PhabricatorFile' => array( 0 => 'PhabricatorFileDAO', - 1 => 'PhabricatorPolicyInterface', + 1 => 'PhabricatorTokenReceiverInterface', + 2 => 'PhabricatorSubscribableInterface', + 3 => 'PhabricatorPolicyInterface', ), + 'PhabricatorFileCommentController' => 'PhabricatorFileController', 'PhabricatorFileController' => 'PhabricatorController', 'PhabricatorFileDAO' => 'PhabricatorLiskDAO', 'PhabricatorFileDataController' => 'PhabricatorFileController', 'PhabricatorFileDeleteController' => 'PhabricatorFileController', 'PhabricatorFileDropUploadController' => 'PhabricatorFileController', + 'PhabricatorFileEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorFileImageMacro' => array( 0 => 'PhabricatorFileDAO', @@ -3275,6 +3288,9 @@ phutil_register_library_map(array( 'PhabricatorFileStorageConfigurationException' => 'Exception', 'PhabricatorFileTestCase' => 'PhabricatorTestCase', 'PhabricatorFileTestDataGenerator' => 'PhabricatorTestDataGenerator', + 'PhabricatorFileTransaction' => 'PhabricatorApplicationTransaction', + 'PhabricatorFileTransactionComment' => 'PhabricatorApplicationTransactionComment', + 'PhabricatorFileTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorFileTransformController' => 'PhabricatorFileController', 'PhabricatorFileUploadController' => 'PhabricatorFileController', 'PhabricatorFileUploadDialogController' => 'PhabricatorFileController', diff --git a/src/applications/files/application/PhabricatorApplicationFiles.php b/src/applications/files/application/PhabricatorApplicationFiles.php index f8d37755a8..05590852b2 100644 --- a/src/applications/files/application/PhabricatorApplicationFiles.php +++ b/src/applications/files/application/PhabricatorApplicationFiles.php @@ -1,5 +1,8 @@ [^/]+)/)?' => 'PhabricatorFileListController', 'upload/' => 'PhabricatorFileUploadController', 'dropupload/' => 'PhabricatorFileDropUploadController', + 'comment/(?P[1-9]\d*)/' => 'PhabricatorFileCommentController', 'delete/(?P[1-9]\d*)/' => 'PhabricatorFileDeleteController', 'info/(?P[^/]+)/' => 'PhabricatorFileInfoController', 'data/(?P[^/]+)/(?P[^/]+)/.*' diff --git a/src/applications/files/conduit/ConduitAPI_file_Method.php b/src/applications/files/conduit/ConduitAPI_file_Method.php index 45f525221d..0c003dd730 100644 --- a/src/applications/files/conduit/ConduitAPI_file_Method.php +++ b/src/applications/files/conduit/ConduitAPI_file_Method.php @@ -1,5 +1,8 @@ setDescription(pht('Allow uploaded files via email.')), + ->setDescription(pht('Allow uploaded files via email.')), + $this->newOption( + 'metamta.files.subject-prefix', + 'string', + '[File]') + ->setDescription(pht('Subject prefix for paste email.')), $this->newOption('files.enable-imagemagick', 'bool', false) ->setBoolOptions( array( diff --git a/src/applications/files/controller/PhabricatorFileCommentController.php b/src/applications/files/controller/PhabricatorFileCommentController.php new file mode 100644 index 0000000000..ab47f9fe0e --- /dev/null +++ b/src/applications/files/controller/PhabricatorFileCommentController.php @@ -0,0 +1,73 @@ +id = idx($data, 'id'); + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + + if (!$request->isFormPost()) { + return new Aphront400Response(); + } + + $file = id(new PhabricatorFileQuery()) + ->setViewer($user) + ->withIDs(array($this->id)) + ->executeOne(); + if (!$file) { + return new Aphront404Response(); + } + + $is_preview = $request->isPreviewRequest(); + $draft = PhabricatorDraft::buildFromRequest($request); + + $view_uri = $file->getInfoURI(); + + $xactions = array(); + $xactions[] = id(new PhabricatorFileTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) + ->attachComment( + id(new PhabricatorFileTransactionComment()) + ->setContent($request->getStr('comment'))); + + $editor = id(new PhabricatorFileEditor()) + ->setActor($user) + ->setContinueOnNoEffect($request->isContinueRequest()) + ->setContentSourceFromRequest($request) + ->setIsPreview($is_preview); + + try { + $xactions = $editor->applyTransactions($file, $xactions); + } catch (PhabricatorApplicationTransactionNoEffectException $ex) { + return id(new PhabricatorApplicationTransactionNoEffectResponse()) + ->setCancelURI($view_uri) + ->setException($ex); + } + + if ($draft) { + $draft->replaceOrDelete(); + } + + if ($request->isAjax()) { + return id(new PhabricatorApplicationTransactionResponse()) + ->setViewer($user) + ->setTransactions($xactions) + ->setIsPreview($is_preview) + ->setAnchorOffset($request->getStr('anchor')); + } else { + return id(new AphrontRedirectResponse()) + ->setURI($view_uri); + } + } + +} diff --git a/src/applications/files/controller/PhabricatorFileInfoController.php b/src/applications/files/controller/PhabricatorFileInfoController.php index 1cb6050ffd..a7c7430982 100644 --- a/src/applications/files/controller/PhabricatorFileInfoController.php +++ b/src/applications/files/controller/PhabricatorFileInfoController.php @@ -21,8 +21,13 @@ final class PhabricatorFileInfoController extends PhabricatorFileController { return new Aphront404Response(); } - $this->loadHandles(array($file->getAuthorPHID())); $phid = $file->getPHID(); + $xactions = id(new PhabricatorFileTransactionQuery()) + ->setViewer($user) + ->withObjectPHIDs(array($phid)) + ->execute(); + + $this->loadHandles(array($file->getAuthorPHID())); $header = id(new PhabricatorHeaderView()) ->setHeader($file->getName()); @@ -36,7 +41,7 @@ final class PhabricatorFileInfoController extends PhabricatorFileController { $actions = $this->buildActionView($file); $properties = $this->buildPropertyView($file); - + $timeline = $this->buildTransactionView($file, $xactions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->setActionList($actions); $crumbs->addCrumb( @@ -50,13 +55,64 @@ final class PhabricatorFileInfoController extends PhabricatorFileController { $header, $actions, $properties, + $timeline ), array( 'title' => $file->getName(), 'device' => true, + 'pageObjects' => array($file->getPHID()), )); } + private function buildTransactionView( + PhabricatorFile $file, + array $xactions) { + + $user = $this->getRequest()->getUser(); + $engine = id(new PhabricatorMarkupEngine()) + ->setViewer($user); + foreach ($xactions as $xaction) { + if ($xaction->getComment()) { + $engine->addObject( + $xaction->getComment(), + PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); + } + } + $engine->process(); + + $timeline = id(new PhabricatorApplicationTransactionView()) + ->setUser($user) + ->setObjectPHID($file->getPHID()) + ->setTransactions($xactions) + ->setMarkupEngine($engine); + + $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); + + $add_comment_header = id(new PhabricatorHeaderView()) + ->setHeader( + $is_serious + ? pht('Add Comment') + : pht('Question File Integrity')); + + $submit_button_name = $is_serious + ? pht('Add Comment') + : pht('Debate the Bits'); + + $draft = PhabricatorDraft::newFromUserAndKey($user, $file->getPHID()); + + $add_comment_form = id(new PhabricatorApplicationTransactionCommentView()) + ->setUser($user) + ->setObjectPHID($file->getPHID()) + ->setDraft($draft) + ->setAction($this->getApplicationURI('/comment/'.$file->getID().'/')) + ->setSubmitButtonName($submit_button_name); + + return array( + $timeline, + $add_comment_header, + $add_comment_form); + } + private function buildActionView(PhabricatorFile $file) { $request = $this->getRequest(); $user = $request->getUser(); diff --git a/src/applications/files/editor/PhabricatorFileEditor.php b/src/applications/files/editor/PhabricatorFileEditor.php new file mode 100644 index 0000000000..d7c2709f79 --- /dev/null +++ b/src/applications/files/editor/PhabricatorFileEditor.php @@ -0,0 +1,89 @@ +getAuthorPHID(), + $this->requireActor()->getPHID(), + ); + } + + protected function buildReplyHandler(PhabricatorLiskDAO $object) { + return id(new FileReplyHandler()) + ->setMailReceiver($object); + } + + protected function buildMailTemplate(PhabricatorLiskDAO $object) { + $id = $object->getID(); + $name = $object->getName(); + + return id(new PhabricatorMetaMTAMail()) + ->setSubject("F{$id}: {$name}") + ->addHeader('Thread-Topic', "F{$id}"); + } + + protected function buildMailBody( + PhabricatorLiskDAO $object, + array $xactions) { + + $body = parent::buildMailBody($object, $xactions); + + $body->addTextSection( + pht('FILE DETAIL'), + PhabricatorEnv::getProductionURI($object->getInfoURI())); + + return $body; + } + + protected function supportsFeed() { + return true; + } + + protected function supportsSearch() { + return false; + } + +} diff --git a/src/applications/files/mail/FilesCreateMailReceiver.php b/src/applications/files/mail/FileCreateMailReceiver.php similarity index 90% rename from src/applications/files/mail/FilesCreateMailReceiver.php rename to src/applications/files/mail/FileCreateMailReceiver.php index c477fb0577..fb11b7ba63 100644 --- a/src/applications/files/mail/FilesCreateMailReceiver.php +++ b/src/applications/files/mail/FileCreateMailReceiver.php @@ -3,7 +3,7 @@ /** * @group files */ -final class FilesCreateMailReceiver +final class FileCreateMailReceiver extends PhabricatorMailReceiver { public function isEnabled() { @@ -48,6 +48,8 @@ final class FilesCreateMailReceiver } else { $subject = pht('You successfully uploaded a file.'); } + $subject_prefix = + PhabricatorEnv::getEnvConfig('metamta.files.subject-prefix'); $file_uris = array(); foreach ($attachment_phids as $phid) { @@ -61,7 +63,8 @@ final class FilesCreateMailReceiver id(new PhabricatorMetaMTAMail()) ->addTos(array($sender->getPHID())) - ->setSubject('[Files] '.$subject) + ->setSubject($subject) + ->setSubjectPrefix($subject_prefix) ->setFrom($sender->getPHID()) ->setRelatedPHID($first_phid) ->setBody($body->render()) diff --git a/src/applications/files/mail/FileMailReceiver.php b/src/applications/files/mail/FileMailReceiver.php new file mode 100644 index 0000000000..a0ab1e9111 --- /dev/null +++ b/src/applications/files/mail/FileMailReceiver.php @@ -0,0 +1,40 @@ +setViewer($viewer) + ->withIDs(array($id)) + ->executeOne(); + } + + protected function processReceivedObjectMail( + PhabricatorMetaMTAReceivedMail $mail, + PhabricatorLiskDAO $object, + PhabricatorUser $sender) { + + $handler = id(new FileReplyHandler()) + ->setMailReceiver($object); + + $handler->setActor($sender); + $handler->setExcludeMailRecipientPHIDs( + $mail->loadExcludeMailRecipientPHIDs()); + $handler->processEmail($mail); + } + +} diff --git a/src/applications/files/mail/FileReplyHandler.php b/src/applications/files/mail/FileReplyHandler.php new file mode 100644 index 0000000000..2f77c815a7 --- /dev/null +++ b/src/applications/files/mail/FileReplyHandler.php @@ -0,0 +1,92 @@ +getDefaultPrivateReplyHandlerEmailAddress($handle, 'F'); + } + + public function getPublicReplyHandlerEmailAddress() { + return $this->getDefaultPublicReplyHandlerEmailAddress('F'); + } + + public function getReplyHandlerInstructions() { + if ($this->supportsReplies()) { + return pht('Reply to comment or !unsubscribe.'); + } else { + return null; + } + } + + protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) { + $actor = $this->getActor(); + $file = $this->getMailReceiver(); + + $body = $mail->getCleanTextBody(); + $body = trim($body); + $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments()); + + $content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_EMAIL, + array( + 'id' => $mail->getID(), + )); + + $lines = explode("\n", trim($body)); + $first_line = head($lines); + + $xactions = array(); + $command = null; + $matches = null; + if (preg_match('/^!(\w+)/', $first_line, $matches)) { + $lines = array_slice($lines, 1); + $body = implode("\n", $lines); + $body = trim($body); + + $command = $matches[1]; + } + + switch ($command) { + case 'unsubscribe': + $xaction = id(new PhabricatorFileTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) + ->setNewValue(array('-' => array($actor->getPHID()))); + $xactions[] = $xaction; + break; + } + + $xactions[] = id(new PhabricatorFileTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) + ->attachComment( + id(new PhabricatorFileTransactionComment()) + ->setContent($body)); + + $editor = id(new PhabricatorFileEditor()) + ->setActor($actor) + ->setContentSource($content_source) + ->setContinueOnNoEffect(true) + ->setIsPreview(false); + + try { + $xactions = $editor->applyTransactions($file, $xactions); + } catch (PhabricatorApplicationTransactionNoEffectException $ex) { + // just do nothing, though unclear why you're sending a blank email + return true; + } + + $head_xaction = head($xactions); + return $head_xaction->getID(); + + } + +} diff --git a/src/applications/files/query/PhabricatorFileQuery.php b/src/applications/files/query/PhabricatorFileQuery.php index 7ce622ead5..12b1907c34 100644 --- a/src/applications/files/query/PhabricatorFileQuery.php +++ b/src/applications/files/query/PhabricatorFileQuery.php @@ -1,5 +1,8 @@ getSecretKey()) { + $this->setSecretKey($this->generateSecretKey()); + } + if (!$this->getMailKey()) { + $this->setMailKey(Filesystem::readRandomCharacters(20)); + } + return parent::save(); + } + public static function readUploadedFileData($spec) { if (!$spec) { throw new Exception("No file was uploaded!"); @@ -648,13 +665,6 @@ final class PhabricatorFile extends PhabricatorFileDAO return ($key == $this->getSecretKey()); } - public function save() { - if (!$this->getSecretKey()) { - $this->setSecretKey($this->generateSecretKey()); - } - return parent::save(); - } - public function generateSecretKey() { return Filesystem::readRandomCharacters(20); } @@ -820,4 +830,23 @@ final class PhabricatorFile extends PhabricatorFileDAO return false; } + +/* -( PhabricatorSubscribableInterface Implementation )-------------------- */ + + + public function isAutomaticallySubscribed($phid) { + return ($this->authorPHID == $phid); + } + + +/* -( PhabricatorTokenReceiverInterface )---------------------------------- */ + + + public function getUsersToNotifyOfTokenGiven() { + return array( + $this->getAuthorPHID(), + ); + } + + } diff --git a/src/applications/files/storage/PhabricatorFileDAO.php b/src/applications/files/storage/PhabricatorFileDAO.php index e8a49b7a46..b8999a7122 100644 --- a/src/applications/files/storage/PhabricatorFileDAO.php +++ b/src/applications/files/storage/PhabricatorFileDAO.php @@ -1,5 +1,8 @@ getTransactionPHID() != null); + } +} diff --git a/src/applications/files/storage/PhabricatorTransformedFile.php b/src/applications/files/storage/PhabricatorTransformedFile.php index e77f1ddffb..cc28210efa 100644 --- a/src/applications/files/storage/PhabricatorTransformedFile.php +++ b/src/applications/files/storage/PhabricatorTransformedFile.php @@ -1,5 +1,8 @@ 'sql', 'name' => $this->getPatchPath('20130826.divinernode.sql'), ), + '20130820.filexactions.sql' => array( + 'type' => 'sql', + 'name' => $this->getPatchPath('20130820.filexactions.sql'), + ), + '20130820.filemailkey.sql' => array( + 'type' => 'sql', + 'name' => $this->getPatchPath('20130820.filemailkey.sql'), + ), + '20130820.file-mailkey-populate.php' => array( + 'type' => 'php', + 'name' => + $this->getPatchPath('20130820.file-mailkey-populate.php'), + ), ); } }