1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-29 00:40:57 +01:00

Paste - add transactions

Summary: Ref T3650. This adds a create transaction, transactions for metadata (title, langauge, view policy), and comments. Editor is used on all create /edit paths.

Test Plan: made some pastes via web and email - yay. edited pastes - yay. verified txns showed up on pastes and in feed correctly.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T3516, T3650

Differential Revision: https://secure.phabricator.com/D6645
This commit is contained in:
Bob Trahan 2013-08-02 12:56:58 -07:00
parent 4a4181aea6
commit 37a5c4b11a
20 changed files with 620 additions and 39 deletions

View file

@ -0,0 +1,46 @@
<?php
$table = new PhabricatorPaste();
$x_table = new PhabricatorPasteTransaction();
$conn_w = $table->establishConnection('w');
$conn_w->openTransaction();
echo "Adding transactions for existing paste objects...\n";
$rows = new LiskRawMigrationIterator($conn_w, 'pastebin_paste');
foreach ($rows as $row) {
$id = $row['id'];
echo "Adding transactions for paste id {$id}...\n";
$xaction_phid = PhabricatorPHID::generateNewPHID(
PhabricatorApplicationTransactionPHIDTypeTransaction::TYPECONST);
queryfx(
$conn_w,
'INSERT INTO %T (phid, authorPHID, objectPHID, viewPolicy, editPolicy,
transactionType, oldValue, newValue,
contentSource, metadata, dateCreated, dateModified)
VALUES (%s, %s, %s, %s, %s, %s, %ns, %ns, %s, %s, %d, %d)',
$x_table->getTableName(),
$xaction_phid,
$row['authorPHID'],
$row['phid'],
'public',
$row['authorPHID'],
PhabricatorPasteTransaction::TYPE_CREATE,
'null',
$row['filePHID'],
PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_LEGACY,
array())->serialize(),
'[]',
$row['dateCreated'],
$row['dateCreated']);
}
$conn_w->saveTransaction();
echo "Done.\n";

View file

@ -0,0 +1,43 @@
CREATE TABLE {$NAMESPACE}_pastebin.pastebin_pastetransaction (
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}_pastebin.pastebin_pastetransaction_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,
lineNumber INT UNSIGNED,
lineLength INT UNSIGNED,
UNIQUE KEY `key_phid` (phid),
UNIQUE KEY `key_version` (transactionPHID, commentVersion)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View file

@ -1364,16 +1364,21 @@ phutil_register_library_map(array(
'PhabricatorPHPMailerConfigOptions' => 'applications/config/option/PhabricatorPHPMailerConfigOptions.php', 'PhabricatorPHPMailerConfigOptions' => 'applications/config/option/PhabricatorPHPMailerConfigOptions.php',
'PhabricatorPagedFormExample' => 'applications/uiexample/examples/PhabricatorPagedFormExample.php', 'PhabricatorPagedFormExample' => 'applications/uiexample/examples/PhabricatorPagedFormExample.php',
'PhabricatorPaste' => 'applications/paste/storage/PhabricatorPaste.php', 'PhabricatorPaste' => 'applications/paste/storage/PhabricatorPaste.php',
'PhabricatorPasteCommentController' => 'applications/paste/controller/PhabricatorPasteCommentController.php',
'PhabricatorPasteConfigOptions' => 'applications/paste/config/PhabricatorPasteConfigOptions.php', 'PhabricatorPasteConfigOptions' => 'applications/paste/config/PhabricatorPasteConfigOptions.php',
'PhabricatorPasteController' => 'applications/paste/controller/PhabricatorPasteController.php', 'PhabricatorPasteController' => 'applications/paste/controller/PhabricatorPasteController.php',
'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php', 'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php',
'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php', 'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php',
'PhabricatorPasteEditor' => 'applications/paste/editor/PhabricatorPasteEditor.php',
'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php', 'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php',
'PhabricatorPastePHIDTypePaste' => 'applications/paste/phid/PhabricatorPastePHIDTypePaste.php', 'PhabricatorPastePHIDTypePaste' => 'applications/paste/phid/PhabricatorPastePHIDTypePaste.php',
'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php', 'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php',
'PhabricatorPasteRemarkupRule' => 'applications/paste/remarkup/PhabricatorPasteRemarkupRule.php', 'PhabricatorPasteRemarkupRule' => 'applications/paste/remarkup/PhabricatorPasteRemarkupRule.php',
'PhabricatorPasteSearchEngine' => 'applications/paste/query/PhabricatorPasteSearchEngine.php', 'PhabricatorPasteSearchEngine' => 'applications/paste/query/PhabricatorPasteSearchEngine.php',
'PhabricatorPasteTestDataGenerator' => 'applications/paste/lipsum/PhabricatorPasteTestDataGenerator.php', 'PhabricatorPasteTestDataGenerator' => 'applications/paste/lipsum/PhabricatorPasteTestDataGenerator.php',
'PhabricatorPasteTransaction' => 'applications/paste/storage/PhabricatorPasteTransaction.php',
'PhabricatorPasteTransactionComment' => 'applications/paste/storage/PhabricatorPasteTransactionComment.php',
'PhabricatorPasteTransactionQuery' => 'applications/paste/query/PhabricatorPasteTransactionQuery.php',
'PhabricatorPasteViewController' => 'applications/paste/controller/PhabricatorPasteViewController.php', 'PhabricatorPasteViewController' => 'applications/paste/controller/PhabricatorPasteViewController.php',
'PhabricatorPeopleController' => 'applications/people/controller/PhabricatorPeopleController.php', 'PhabricatorPeopleController' => 'applications/people/controller/PhabricatorPeopleController.php',
'PhabricatorPeopleEditController' => 'applications/people/controller/PhabricatorPeopleEditController.php', 'PhabricatorPeopleEditController' => 'applications/people/controller/PhabricatorPeopleEditController.php',
@ -3406,10 +3411,12 @@ phutil_register_library_map(array(
1 => 'PhabricatorTokenReceiverInterface', 1 => 'PhabricatorTokenReceiverInterface',
2 => 'PhabricatorPolicyInterface', 2 => 'PhabricatorPolicyInterface',
), ),
'PhabricatorPasteCommentController' => 'PhabricatorPasteController',
'PhabricatorPasteConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorPasteConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPasteController' => 'PhabricatorController', 'PhabricatorPasteController' => 'PhabricatorController',
'PhabricatorPasteDAO' => 'PhabricatorLiskDAO', 'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
'PhabricatorPasteEditController' => 'PhabricatorPasteController', 'PhabricatorPasteEditController' => 'PhabricatorPasteController',
'PhabricatorPasteEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorPasteListController' => 'PhabricatorPasteListController' =>
array( array(
0 => 'PhabricatorPasteController', 0 => 'PhabricatorPasteController',
@ -3420,6 +3427,9 @@ phutil_register_library_map(array(
'PhabricatorPasteRemarkupRule' => 'PhabricatorRemarkupRuleObject', 'PhabricatorPasteRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'PhabricatorPasteSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorPasteSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorPasteTestDataGenerator' => 'PhabricatorTestDataGenerator', 'PhabricatorPasteTestDataGenerator' => 'PhabricatorTestDataGenerator',
'PhabricatorPasteTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorPasteTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhabricatorPasteTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorPasteViewController' => 'PhabricatorPasteController', 'PhabricatorPasteViewController' => 'PhabricatorPasteController',
'PhabricatorPeopleController' => 'PhabricatorController', 'PhabricatorPeopleController' => 'PhabricatorController',
'PhabricatorPeopleEditController' => 'PhabricatorPeopleController', 'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',

View file

@ -1,5 +1,8 @@
<?php <?php
/**
* group paste
*/
final class PhabricatorApplicationPaste extends PhabricatorApplication { final class PhabricatorApplicationPaste extends PhabricatorApplication {
public function getBaseURI() { public function getBaseURI() {
@ -35,6 +38,7 @@ final class PhabricatorApplicationPaste extends PhabricatorApplication {
'(query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorPasteListController', '(query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorPasteListController',
'create/' => 'PhabricatorPasteEditController', 'create/' => 'PhabricatorPasteEditController',
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteEditController', 'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteEditController',
'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteCommentController',
), ),
); );
} }

View file

@ -0,0 +1,73 @@
<?php
/**
* @group paste
*/
final class PhabricatorPasteCommentController
extends PhabricatorPasteController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
if (!$request->isFormPost()) {
return new Aphront400Response();
}
$paste = id(new PhabricatorPasteQuery())
->setViewer($user)
->withIDs(array($this->id))
->executeOne();
if (!$paste) {
return new Aphront404Response();
}
$is_preview = $request->isPreviewRequest();
$draft = PhabricatorDraft::buildFromRequest($request);
$view_uri = $paste->getURI();
$xactions = array();
$xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
->attachComment(
id(new PhabricatorPasteTransactionComment())
->setContent($request->getStr('comment')));
$editor = id(new PhabricatorPasteEditor())
->setActor($user)
->setContinueOnNoEffect($request->isContinueRequest())
->setContentSourceFromRequest($request)
->setIsPreview($is_preview);
try {
$xactions = $editor->applyTransactions($paste, $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);
}
}
}

View file

@ -1,5 +1,8 @@
<?php <?php
/**
* @group paste
*/
abstract class PhabricatorPasteController extends PhabricatorController { abstract class PhabricatorPasteController extends PhabricatorController {
public function buildSideNavView($for_app = false) { public function buildSideNavView($for_app = false) {

View file

@ -1,5 +1,8 @@
<?php <?php
/**
* @group paste
*/
final class PhabricatorPasteEditController extends PhabricatorPasteController { final class PhabricatorPasteEditController extends PhabricatorPasteController {
private $id; private $id;
@ -59,44 +62,64 @@ final class PhabricatorPasteEditController extends PhabricatorPasteController {
$text = null; $text = null;
$e_text = true; $e_text = true;
$errors = array(); $errors = array();
if ($is_create && $parent) {
$v_title = pht('Fork of %s', $parent->getFullName());
$v_language = $parent->getLanguage();
$v_text = $parent->getRawContent();
} else {
$v_title = $paste->getTitle();
$v_language = $paste->getLanguage();
$v_text = '';
}
$v_policy = $paste->getViewPolicy();
if ($request->isFormPost()) { if ($request->isFormPost()) {
$xactions = array();
if ($is_create) { if ($is_create) {
$text = $request->getStr('text'); $v_text = $request->getStr('text');
if (!strlen($text)) { if (!strlen($v_text)) {
$e_text = pht('Required'); $e_text = pht('Required');
$errors[] = pht('The paste may not be blank.'); $errors[] = pht('The paste may not be blank.');
} else { } else {
$e_text = null; $e_text = null;
} }
} }
$paste->setTitle($request->getStr('title')); $v_title = $request->getStr('title');
$paste->setLanguage($request->getStr('language')); $v_language = $request->getStr('language');
$paste->setViewPolicy($request->getStr('can_view')); $v_policy = $request->getStr('can_view');
// NOTE: The author is the only editor and can always view the paste, // NOTE: The author is the only editor and can always view the paste,
// so it's impossible for them to choose an invalid policy. // so it's impossible for them to choose an invalid policy.
if (!$errors) { if (!$errors) {
if ($is_create) { if ($is_create) {
$paste_file = PhabricatorFile::newFromFileData( $xactions[] = id(new PhabricatorPasteTransaction())
$text, ->setTransactionType(PhabricatorPasteTransaction::TYPE_CREATE)
array( ->setNewValue(array(
'name' => $paste->getTitle(), 'title' => $v_title,
'mime-type' => 'text/plain; charset=utf-8', 'text' => $v_text));
'authorPHID' => $user->getPHID(),
));
$paste->setFilePHID($paste_file->getPHID());
} }
$paste->save(); $xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorPasteTransaction::TYPE_TITLE)
->setNewValue($v_title);
$xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorPasteTransaction::TYPE_LANGUAGE)
->setNewValue($v_language);
$xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
->setNewValue($v_policy);
$editor = id(new PhabricatorPasteEditor())
->setActor($user)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
$xactions = $editor->applyTransactions($paste, $xactions);
return id(new AphrontRedirectResponse())->setURI($paste->getURI()); return id(new AphrontRedirectResponse())->setURI($paste->getURI());
} } else {
} else { // make sure we update policy so its correctly populated to what
if ($is_create && $parent) { // the user chose
$paste->setTitle(pht('Fork of %s', $parent->getFullName())); $paste->setViewPolicy($v_policy);
$paste->setLanguage($parent->getLanguage());
$text = $parent->getRawContent();
} }
} }
@ -120,13 +143,13 @@ final class PhabricatorPasteEditController extends PhabricatorPasteController {
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setLabel(pht('Title')) ->setLabel(pht('Title'))
->setValue($paste->getTitle()) ->setValue($v_title)
->setName('title')) ->setName('title'))
->appendChild( ->appendChild(
id(new AphrontFormSelectControl()) id(new AphrontFormSelectControl())
->setLabel(pht('Language')) ->setLabel(pht('Language'))
->setName('language') ->setName('language')
->setValue($paste->getLanguage()) ->setValue($v_language)
->setOptions($langs)); ->setOptions($langs));
$policies = id(new PhabricatorPolicyQuery()) $policies = id(new PhabricatorPolicyQuery())
@ -148,7 +171,7 @@ final class PhabricatorPasteEditController extends PhabricatorPasteController {
id(new AphrontFormTextAreaControl()) id(new AphrontFormTextAreaControl())
->setLabel(pht('Text')) ->setLabel(pht('Text'))
->setError($e_text) ->setError($e_text)
->setValue($text) ->setValue($v_text)
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL) ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
->setCustomClass('PhabricatorMonospaced') ->setCustomClass('PhabricatorMonospaced')
->setName('text')); ->setName('text'));

View file

@ -1,5 +1,8 @@
<?php <?php
/**
* @group paste
*/
final class PhabricatorPasteListController extends PhabricatorPasteController final class PhabricatorPasteListController extends PhabricatorPasteController
implements PhabricatorApplicationSearchResultsControllerInterface { implements PhabricatorApplicationSearchResultsControllerInterface {

View file

@ -1,5 +1,8 @@
<?php <?php
/**
* group paste
*/
final class PhabricatorPasteViewController extends PhabricatorPasteController { final class PhabricatorPasteViewController extends PhabricatorPasteController {
private $id; private $id;
@ -58,6 +61,49 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController {
->setName('P'.$paste->getID()) ->setName('P'.$paste->getID())
->setHref('/P'.$paste->getID())); ->setHref('/P'.$paste->getID()));
$xactions = id(new PhabricatorPasteTransactionQuery())
->setViewer($request->getUser())
->withObjectPHIDs(array($paste->getPHID()))
->execute();
$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($paste->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('Debate Paste Accuracy'));
$submit_button_name = $is_serious
? pht('Add Comment')
: pht('Pity the Fool');
$draft = PhabricatorDraft::newFromUserAndKey($user, $paste->getPHID());
$add_comment_form = id(new PhabricatorApplicationTransactionCommentView())
->setUser($user)
->setObjectPHID($paste->getPHID())
->setDraft($draft)
->setAction($this->getApplicationURI('/comment/'.$paste->getID().'/'))
->setSubmitButtonName($submit_button_name);
return $this->buildApplicationPage( return $this->buildApplicationPage(
array( array(
$crumbs, $crumbs,
@ -65,6 +111,9 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController {
$actions, $actions,
$properties, $properties,
$source_code, $source_code,
$timeline,
$add_comment_header,
$add_comment_form
), ),
array( array(
'title' => $paste->getFullName(), 'title' => $paste->getFullName(),

View file

@ -0,0 +1,126 @@
<?php
/**
* @group paste
*/
final class PhabricatorPasteEditor
extends PhabricatorApplicationTransactionEditor {
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = PhabricatorPasteTransaction::TYPE_CREATE;
$types[] = PhabricatorPasteTransaction::TYPE_TITLE;
$types[] = PhabricatorPasteTransaction::TYPE_LANGUAGE;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_COMMENT;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorPasteTransaction::TYPE_CREATE:
return null;
case PhabricatorPasteTransaction::TYPE_TITLE:
return $object->getTitle();
case PhabricatorPasteTransaction::TYPE_LANGUAGE:
return $object->getLanguage();
}
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorPasteTransaction::TYPE_CREATE:
// this was set via applyInitialEffects
return $object->getFilePHID();
case PhabricatorPasteTransaction::TYPE_TITLE:
case PhabricatorPasteTransaction::TYPE_LANGUAGE:
return $xaction->getNewValue();
}
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorPasteTransaction::TYPE_TITLE:
$object->setTitle($xaction->getNewValue());
break;
case PhabricatorPasteTransaction::TYPE_LANGUAGE:
$object->setLanguage($xaction->getNewValue());
break;
}
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
}
protected function shouldApplyInitialEffects(
PhabricatorLiskDAO $object,
array $xactions) {
foreach ($xactions as $xaction) {
if ($xaction->getTransactionType() ==
PhabricatorPasteTransaction::TYPE_CREATE) {
return true;
}
}
return false;
}
protected function applyInitialEffects(
PhabricatorLiskDAO $object,
array $xactions) {
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorPasteTransaction::TYPE_CREATE:
$data = $xaction->getNewValue();
$paste_file = PhabricatorFile::newFromFileData(
$data['text'],
array(
'name' => $data['title'],
'mime-type' => 'text/plain; charset=utf-8',
'authorPHID' => $this->getActor()->getPHID(),
));
$object->setFilePHID($paste_file->getPHID());
break;
}
}
}
protected function supportsMail() {
return false;
}
protected function getMailTo(PhabricatorLiskDAO $object) {
return array(
$object->getAuthorPHID(),
$this->requireActor()->getPHID(),
);
}
protected function getMailCC(PhabricatorLiskDAO $object) {
return array();
}
protected function supportsFeed() {
return true;
}
protected function supportsSearch() {
return false;
}
}

View file

@ -35,21 +35,34 @@ final class PasteCreateMailReceiver
if (!$title) { if (!$title) {
$title = pht('Pasted via email.'); $title = pht('Pasted via email.');
} }
$paste_file = PhabricatorFile::newFromFileData( $xactions = array();
$mail->getCleanTextBody(), $xactions[] = id(new PhabricatorPasteTransaction())
array( ->setTransactionType(PhabricatorPasteTransaction::TYPE_CREATE)
'name' => $title, ->setNewValue(array(
'mime-type' => 'text/plain; charset=utf-8', 'title' => $title,
'authorPHID' => $sender->getPHID(), 'text' => $mail->getCleanTextBody()));
)); $xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorPasteTransaction::TYPE_TITLE)
->setNewValue($title);
$xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorPasteTransaction::TYPE_LANGUAGE)
->setNewValue(''); // auto-detect
$xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
->setNewValue(PhabricatorPolicies::POLICY_USER);
$paste = id(new PhabricatorPaste()) $paste = id(new PhabricatorPaste())
->setAuthorPHID($sender->getPHID()) ->setAuthorPHID($sender->getPHID());
->setTitle($title) $content_source = PhabricatorContentSource::newForSource(
->setFilePHID($paste_file->getPHID()) PhabricatorContentSource::SOURCE_EMAIL,
->setLanguage('') // auto-detect array(
->setViewPolicy(PhabricatorPolicies::POLICY_USER) 'id' => $mail->getID(),
->save(); ));
$editor = id(new PhabricatorPasteEditor())
->setActor($sender)
->setContentSource($content_source)
->setContinueOnNoEffect(true);
$xactions = $editor->applyTransactions($paste, $xactions);
$mail->setRelatedPHID($paste->getPHID()); $mail->setRelatedPHID($paste->getPHID());

View file

@ -38,7 +38,7 @@ final class PhabricatorPastePHIDTypePaste extends PhabricatorPHIDType {
$name = $paste->getFullName(); $name = $paste->getFullName();
$handle->setName("P{$id}"); $handle->setName("P{$id}");
$handle->setFullName("P{$id}: {$name}"); $handle->setFullName($name);
$handle->setURI("/P{$id}"); $handle->setURI("/P{$id}");
} }
} }

View file

@ -1,5 +1,8 @@
<?php <?php
/**
* @group paste
*/
final class PhabricatorPasteQuery final class PhabricatorPasteQuery
extends PhabricatorCursorPagedPolicyAwareQuery { extends PhabricatorCursorPagedPolicyAwareQuery {

View file

@ -1,5 +1,8 @@
<?php <?php
/**
* @group paste
*/
final class PhabricatorPasteSearchEngine final class PhabricatorPasteSearchEngine
extends PhabricatorApplicationSearchEngine { extends PhabricatorApplicationSearchEngine {

View file

@ -0,0 +1,13 @@
<?php
/**
* @group paste
*/
final class PhabricatorPasteTransactionQuery
extends PhabricatorApplicationTransactionQuery {
public function getTemplateApplicationTransaction() {
return new PhabricatorPasteTransaction();
}
}

View file

@ -1,5 +1,8 @@
<?php <?php
/**
* @group paste
*/
final class PhabricatorPaste extends PhabricatorPasteDAO final class PhabricatorPaste extends PhabricatorPasteDAO
implements PhabricatorTokenReceiverInterface, PhabricatorPolicyInterface { implements PhabricatorTokenReceiverInterface, PhabricatorPolicyInterface {

View file

@ -0,0 +1,138 @@
<?php
/**
* @group paste
*/
final class PhabricatorPasteTransaction
extends PhabricatorApplicationTransaction {
const TYPE_CREATE = 'paste.create';
const TYPE_TITLE = 'paste.title';
const TYPE_LANGUAGE = 'paste.language';
public function getApplicationName() {
return 'pastebin';
}
public function getApplicationTransactionType() {
return PhabricatorPastePHIDTypePaste::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return new PhabricatorPasteTransactionComment();
}
public function getApplicationObjectTypeName() {
return pht('paste');
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
switch ($this->getTransactionType()) {
case self::TYPE_CREATE:
$phids[] = $this->getObjectPHID();
break;
}
return $phids;
}
public function shouldHide() {
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
case self::TYPE_LANGUAGE:
return $old === null;
}
return parent::shouldHide();
}
public function getIcon() {
switch ($this->getTransactionType()) {
case self::TYPE_CREATE:
return 'create';
break;
case self::TYPE_TITLE:
case self::TYPE_LANGUAGE:
return 'edit';
break;
}
return parent::getIcon();
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$object_phid = $this->getObjectPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
$type = $this->getTransactionType();
switch ($type) {
case PhabricatorPasteTransaction::TYPE_CREATE:
return pht(
'%s created "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
case PhabricatorPasteTransaction::TYPE_TITLE:
return pht(
'%s updated the paste\'s title to "%s".',
$this->renderHandleLink($author_phid),
$new);
break;
case PhabricatorPasteTransaction::TYPE_LANGUAGE:
return pht(
"%s updated the paste's language.",
$this->renderHandleLink($author_phid));
break;
}
return parent::getTitle();
}
public function getTitleForFeed() {
$author_phid = $this->getAuthorPHID();
$object_phid = $this->getObjectPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
$type = $this->getTransactionType();
switch ($type) {
case PhabricatorPasteTransaction::TYPE_CREATE:
return pht(
'%s created %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
case PhabricatorPasteTransaction::TYPE_TITLE:
return pht(
'%s updated the title for %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
case PhabricatorPasteTransaction::TYPE_LANGUAGE:
return pht(
'%s update the language for %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
}
return parent::getTitleForFeed();
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case PhabricatorPasteTransaction::TYPE_CREATE:
return PhabricatorTransactions::COLOR_GREEN;
}
return parent::getColor();
}
}

View file

@ -0,0 +1,20 @@
<?php
/**
* @group paste
*/
final class PhabricatorPasteTransactionComment
extends PhabricatorApplicationTransactionComment {
protected $lineNumber;
protected $lineLength;
public function getApplicationTransactionObject() {
return new PhabricatorPasteTransaction();
}
public function shouldUseMarkupCache($field) {
// Only cache submitted comments.
return ($this->getTransactionPHID() != null);
}
}

View file

@ -1499,6 +1499,14 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
'type' => 'php', 'type' => 'php',
'name' => $this->getPatchPath('20130728.ponderxcomment.php'), 'name' => $this->getPatchPath('20130728.ponderxcomment.php'),
), ),
'20130801.pastexactions.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130801.pastexactions.sql'),
),
'20130801.pastexactions.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('20130801.pastexactions.php'),
),
); );
} }
} }