mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-19 13:22:42 +01:00
Phriction - move "move" to modern editor + transactions
Summary: Ref T4029. Much like D10756, D10761 this does the bare minimum to get things in there. I have a sticky with "TODOs" about moving the error-checking business logic into the editor in all three cases. Up next - policy... Test Plan: moved a document and it worked! verified no feed story. verified both documents involved looked good Reviewers: epriestley Reviewed By: epriestley Subscribers: epriestley, Korvin Maniphest Tasks: T4029 Differential Revision: https://secure.phabricator.com/D10763
This commit is contained in:
parent
bdbb771830
commit
dd7d8cf910
3 changed files with 169 additions and 51 deletions
|
@ -16,6 +16,7 @@ final class PhrictionMoveController extends PhrictionController {
|
|||
$document = id(new PhrictionDocumentQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->id))
|
||||
->needContent(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
|
@ -32,6 +33,7 @@ final class PhrictionMoveController extends PhrictionController {
|
|||
$document = id(new PhrictionDocumentQuery())
|
||||
->setViewer($user)
|
||||
->withSlugs(array($slug))
|
||||
->needContent(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
|
@ -74,50 +76,46 @@ final class PhrictionMoveController extends PhrictionController {
|
|||
return id(new AphrontDialogResponse())->setDialog($error_dialog);
|
||||
}
|
||||
|
||||
$content = id(new PhrictionContent())->load($document->getContentID());
|
||||
$content = $document->getContent();
|
||||
|
||||
if ($request->isFormPost() && !count($errors)) {
|
||||
if (!count($errors)) { // First check if the target document exists
|
||||
|
||||
// NOTE: We use the ominpotent user because we can't let users overwrite
|
||||
// documents even if they can't see them.
|
||||
$target_document = id(new PhrictionDocumentQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withSlugs(array($target_slug))
|
||||
->executeOne();
|
||||
// NOTE: We use the ominpotent user because we can't let users overwrite
|
||||
// documents even if they can't see them.
|
||||
$target_document = id(new PhrictionDocumentQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withSlugs(array($target_slug))
|
||||
->needContent(true)
|
||||
->executeOne();
|
||||
|
||||
// Considering to overwrite existing docs? Nuke this!
|
||||
if ($target_document && $target_document->getStatus() ==
|
||||
PhrictionDocumentStatus::STATUS_EXISTS) {
|
||||
|
||||
$errors[] = pht('Can not overwrite existing target document.');
|
||||
$e_url = pht('Already exists.');
|
||||
}
|
||||
// Considering to overwrite existing docs? Nuke this!
|
||||
$exists = PhrictionDocumentStatus::STATUS_EXISTS;
|
||||
if ($target_document && $target_document->getStatus() == $exists) {
|
||||
$errors[] = pht('Can not overwrite existing target document.');
|
||||
$e_url = pht('Already exists.');
|
||||
}
|
||||
|
||||
if (!count($errors)) { // I like to move it, move it!
|
||||
$from_editor = id(PhrictionDocumentEditor::newForSlug($slug))
|
||||
if (!count($errors)) {
|
||||
|
||||
$editor = id(new PhrictionTransactionEditor())
|
||||
->setActor($user)
|
||||
->setTitle($content->getTitle())
|
||||
->setContent($content->getContent())
|
||||
->setDescription($content->getDescription());
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setDescription($request->getStr('description'));
|
||||
|
||||
$target_editor = id(PhrictionDocumentEditor::newForSlug(
|
||||
$target_slug))
|
||||
->setActor($user)
|
||||
->setTitle($content->getTitle())
|
||||
->setContent($content->getContent())
|
||||
->setDescription($content->getDescription());
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhrictionTransaction())
|
||||
->setTransactionType(PhrictionTransaction::TYPE_MOVE_TO)
|
||||
->setNewValue($document);
|
||||
if (!$target_document) {
|
||||
$target_document = PhrictionDocument::initializeNewDocument(
|
||||
$user,
|
||||
$target_slug);
|
||||
}
|
||||
$editor->applyTransactions($target_document, $xactions);
|
||||
|
||||
// Move it!
|
||||
$target_editor->moveHere($document->getID(), $document->getPHID());
|
||||
|
||||
// Retrieve the target doc directly from the editor
|
||||
// No need to load it per Sql again
|
||||
$target_document = $target_editor->getDocument();
|
||||
$from_editor->moveAway($target_document->getID());
|
||||
|
||||
$redir_uri = PhrictionDocument::getSlugURI($target_document->getSlug());
|
||||
$redir_uri = PhrictionDocument::getSlugURI(
|
||||
$target_document->getSlug());
|
||||
return id(new AphrontRedirectResponse())->setURI($redir_uri);
|
||||
}
|
||||
}
|
||||
|
@ -131,21 +129,21 @@ final class PhrictionMoveController extends PhrictionController {
|
|||
->setUser($user)
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel(pht('Title'))
|
||||
->setValue($content->getTitle()))
|
||||
->setLabel(pht('Title'))
|
||||
->setValue($content->getTitle()))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('New URI'))
|
||||
->setValue($target_slug)
|
||||
->setError($e_url)
|
||||
->setName('new-slug')
|
||||
->setCaption(pht('The new location of the document.')))
|
||||
->setLabel(pht('New URI'))
|
||||
->setValue($target_slug)
|
||||
->setError($e_url)
|
||||
->setName('new-slug')
|
||||
->setCaption(pht('The new location of the document.')))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Edit Notes'))
|
||||
->setValue($content->getDescription())
|
||||
->setError(null)
|
||||
->setName('description'));
|
||||
->setLabel(pht('Edit Notes'))
|
||||
->setValue($content->getDescription())
|
||||
->setError(null)
|
||||
->setName('description'));
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($user)
|
||||
|
|
|
@ -6,6 +6,7 @@ final class PhrictionTransactionEditor
|
|||
private $description;
|
||||
private $oldContent;
|
||||
private $newContent;
|
||||
private $moveAwayDocument;
|
||||
|
||||
public function setDescription($description) {
|
||||
$this->description = $description;
|
||||
|
@ -49,6 +50,8 @@ final class PhrictionTransactionEditor
|
|||
$types[] = PhrictionTransaction::TYPE_TITLE;
|
||||
$types[] = PhrictionTransaction::TYPE_CONTENT;
|
||||
$types[] = PhrictionTransaction::TYPE_DELETE;
|
||||
$types[] = PhrictionTransaction::TYPE_MOVE_TO;
|
||||
$types[] = PhrictionTransaction::TYPE_MOVE_AWAY;
|
||||
|
||||
/* TODO
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
|
@ -74,6 +77,8 @@ final class PhrictionTransactionEditor
|
|||
}
|
||||
return $this->getOldContent()->getContent();
|
||||
case PhrictionTransaction::TYPE_DELETE:
|
||||
case PhrictionTransaction::TYPE_MOVE_TO:
|
||||
case PhrictionTransaction::TYPE_MOVE_AWAY:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +92,22 @@ final class PhrictionTransactionEditor
|
|||
case PhrictionTransaction::TYPE_CONTENT:
|
||||
case PhrictionTransaction::TYPE_DELETE:
|
||||
return $xaction->getNewValue();
|
||||
case PhrictionTransaction::TYPE_MOVE_TO:
|
||||
$document = $xaction->getNewValue();
|
||||
// grab the real object now for the sub-editor to come
|
||||
$this->moveAwayDocument = $document;
|
||||
$dict = array(
|
||||
'id' => $document->getID(),
|
||||
'phid' => $document->getPHID(),
|
||||
'content' => $document->getContent()->getContent(),);
|
||||
return $dict;
|
||||
case PhrictionTransaction::TYPE_MOVE_AWAY:
|
||||
$document = $xaction->getNewValue();
|
||||
$dict = array(
|
||||
'id' => $document->getID(),
|
||||
'phid' => $document->getPHID(),
|
||||
'content' => $document->getContent()->getContent(),);
|
||||
return $dict;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,6 +120,8 @@ final class PhrictionTransactionEditor
|
|||
case PhrictionTransaction::TYPE_TITLE:
|
||||
case PhrictionTransaction::TYPE_CONTENT:
|
||||
case PhrictionTransaction::TYPE_DELETE:
|
||||
case PhrictionTransaction::TYPE_MOVE_TO:
|
||||
case PhrictionTransaction::TYPE_MOVE_AWAY:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -120,8 +143,12 @@ final class PhrictionTransactionEditor
|
|||
switch ($xaction->getTransactionType()) {
|
||||
case PhrictionTransaction::TYPE_TITLE:
|
||||
case PhrictionTransaction::TYPE_CONTENT:
|
||||
case PhrictionTransaction::TYPE_MOVE_TO:
|
||||
$object->setStatus(PhrictionDocumentStatus::STATUS_EXISTS);
|
||||
return;
|
||||
case PhrictionTransaction::TYPE_MOVE_AWAY:
|
||||
$object->setStatus(PhrictionDocumentStatus::STATUS_MOVED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,6 +168,20 @@ final class PhrictionTransactionEditor
|
|||
$this->getNewContent()->setChangeType(
|
||||
PhrictionChangeType::CHANGE_DELETE);
|
||||
break;
|
||||
case PhrictionTransaction::TYPE_MOVE_TO:
|
||||
$dict = $xaction->getNewValue();
|
||||
$this->getNewContent()->setContent($dict['content']);
|
||||
$this->getNewContent()->setChangeType(
|
||||
PhrictionChangeType::CHANGE_MOVE_HERE);
|
||||
$this->getNewContent()->setChangeRef($dict['id']);
|
||||
break;
|
||||
case PhrictionTransaction::TYPE_MOVE_AWAY:
|
||||
$dict = $xaction->getNewValue();
|
||||
$this->getNewContent()->setContent('');
|
||||
$this->getNewContent()->setChangeType(
|
||||
PhrictionChangeType::CHANGE_MOVE_AWAY);
|
||||
$this->getNewContent()->setChangeRef($dict['id']);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -156,6 +197,8 @@ final class PhrictionTransactionEditor
|
|||
case PhrictionTransaction::TYPE_TITLE:
|
||||
case PhrictionTransaction::TYPE_CONTENT:
|
||||
case PhrictionTransaction::TYPE_DELETE:
|
||||
case PhrictionTransaction::TYPE_MOVE_AWAY:
|
||||
case PhrictionTransaction::TYPE_MOVE_TO:
|
||||
$save_content = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -196,15 +239,27 @@ final class PhrictionTransactionEditor
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->moveAwayDocument !== null) {
|
||||
$move_away_xactions = array();
|
||||
$move_away_xactions[] = id(new PhrictionTransaction())
|
||||
->setTransactionType(PhrictionTransaction::TYPE_MOVE_AWAY)
|
||||
->setNewValue($object);
|
||||
$sub_editor = id(new PhrictionTransactionEditor())
|
||||
->setActor($this->getActor())
|
||||
->setContentSource($this->getContentSource())
|
||||
->setContinueOnNoEffect($this->getContinueOnNoEffect())
|
||||
->setDescription($this->getDescription())
|
||||
->applyTransactions($this->moveAwayDocument, $move_away_xactions);
|
||||
}
|
||||
|
||||
return $xactions;
|
||||
}
|
||||
|
||||
protected function shouldSendMail(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
|
||||
$xactions = mfilter($xactions, 'shouldHide', true);
|
||||
return $xactions;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getMailSubjectPrefix() {
|
||||
|
@ -274,8 +329,16 @@ final class PhrictionTransactionEditor
|
|||
array $xactions) {
|
||||
|
||||
$phids = parent::getFeedRelatedPHIDs($object, $xactions);
|
||||
// TODO - once the editor supports moves, we'll need to surface the
|
||||
// "from document phid" to related phids.
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhrictionTransaction::TYPE_MOVE_TO:
|
||||
$dict = $xaction->getNewValue();
|
||||
$phids[] = $dict['phid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ final class PhrictionTransaction
|
|||
const TYPE_TITLE = 'title';
|
||||
const TYPE_CONTENT = 'content';
|
||||
const TYPE_DELETE = 'delete';
|
||||
const TYPE_MOVE_TO = 'move-to';
|
||||
const TYPE_MOVE_AWAY = 'move-away';
|
||||
|
||||
const MAILTAG_TITLE = 'phriction-title';
|
||||
const MAILTAG_CONTENT = 'phriction-content';
|
||||
|
@ -23,6 +25,20 @@ final class PhrictionTransaction
|
|||
return new PhrictionTransactionComment();
|
||||
}
|
||||
|
||||
public function getRequiredHandlePHIDs() {
|
||||
$phids = parent::getRequiredHandlePHIDs();
|
||||
$new = $this->getNewValue();
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_MOVE_TO:
|
||||
case self::TYPE_MOVE_AWAY:
|
||||
$phids[] = $new['phid'];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
public function getRemarkupBlocks() {
|
||||
$blocks = parent::getRemarkupBlocks();
|
||||
|
||||
|
@ -49,6 +65,24 @@ final class PhrictionTransaction
|
|||
return parent::shouldHide();
|
||||
}
|
||||
|
||||
public function shouldHideForMail(array $xactions) {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_MOVE_TO:
|
||||
case self::TYPE_MOVE_AWAY:
|
||||
return true;
|
||||
}
|
||||
return parent::shouldHideForMail($xactions);
|
||||
}
|
||||
|
||||
public function shouldHideForFeed() {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_MOVE_TO:
|
||||
case self::TYPE_MOVE_AWAY:
|
||||
return true;
|
||||
}
|
||||
return parent::shouldHideForFeed();
|
||||
}
|
||||
|
||||
public function getActionStrength() {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_TITLE:
|
||||
|
@ -57,6 +91,9 @@ final class PhrictionTransaction
|
|||
return 1.3;
|
||||
case self::TYPE_DELETE:
|
||||
return 1.5;
|
||||
case self::TYPE_MOVE_TO:
|
||||
case self::TYPE_MOVE_AWAY:
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return parent::getActionStrength();
|
||||
|
@ -80,6 +117,12 @@ final class PhrictionTransaction
|
|||
case self::TYPE_DELETE:
|
||||
return pht('Deleted');
|
||||
|
||||
case self::TYPE_MOVE_TO:
|
||||
return pht('Moved');
|
||||
|
||||
case self::TYPE_MOVE_AWAY:
|
||||
return pht('Moved Away');
|
||||
|
||||
}
|
||||
|
||||
return parent::getActionName();
|
||||
|
@ -95,6 +138,9 @@ final class PhrictionTransaction
|
|||
return 'fa-pencil';
|
||||
case self::TYPE_DELETE:
|
||||
return 'fa-times';
|
||||
case self::TYPE_MOVE_TO:
|
||||
case self::TYPE_MOVE_AWAY:
|
||||
return 'fa-arrows';
|
||||
}
|
||||
|
||||
return parent::getIcon();
|
||||
|
@ -130,6 +176,17 @@ final class PhrictionTransaction
|
|||
'%s deleted this document.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
|
||||
case self::TYPE_MOVE_TO:
|
||||
return pht(
|
||||
'%s moved this document from %s',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($new['phid']));
|
||||
|
||||
case self::TYPE_MOVE_AWAY:
|
||||
return pht(
|
||||
'%s moved this document to %s',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($new['phid']));
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue