1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 23:02:42 +01:00

Allow the published version of a Phriction document to differ from the most recent version

Summary:
Depends on D19620. Ref T13077. This adds a "Publish" operation which points the current version at some historical version of the document -- not necessarily the most recent version. Newer versions become "drafts".

This is still quite rough and missing a lot of hinting in the UI, I'm just making it work so I can start making the UI understand it.

Test Plan: Used the "Publish" action to publish older versions of a document, saw the document revert. Many UI hints are missing and this operation is puzzling and not yet usable for normal users.

Reviewers: amckinley

Maniphest Tasks: T13077

Differential Revision: https://secure.phabricator.com/D19621
This commit is contained in:
epriestley 2018-08-28 15:43:40 -07:00
parent 50f4adef64
commit 349686319e
6 changed files with 200 additions and 3 deletions

View file

@ -5029,6 +5029,7 @@ phutil_register_library_map(array(
'PhrictionDocumentPHIDType' => 'applications/phriction/phid/PhrictionDocumentPHIDType.php',
'PhrictionDocumentPathHeraldField' => 'applications/phriction/herald/PhrictionDocumentPathHeraldField.php',
'PhrictionDocumentPolicyCodex' => 'applications/phriction/codex/PhrictionDocumentPolicyCodex.php',
'PhrictionDocumentPublishTransaction' => 'applications/phriction/xaction/PhrictionDocumentPublishTransaction.php',
'PhrictionDocumentQuery' => 'applications/phriction/query/PhrictionDocumentQuery.php',
'PhrictionDocumentSearchConduitAPIMethod' => 'applications/phriction/conduit/PhrictionDocumentSearchConduitAPIMethod.php',
'PhrictionDocumentSearchEngine' => 'applications/phriction/query/PhrictionDocumentSearchEngine.php',
@ -5046,6 +5047,7 @@ phutil_register_library_map(array(
'PhrictionMarkupPreviewController' => 'applications/phriction/controller/PhrictionMarkupPreviewController.php',
'PhrictionMoveController' => 'applications/phriction/controller/PhrictionMoveController.php',
'PhrictionNewController' => 'applications/phriction/controller/PhrictionNewController.php',
'PhrictionPublishController' => 'applications/phriction/controller/PhrictionPublishController.php',
'PhrictionRemarkupRule' => 'applications/phriction/markup/PhrictionRemarkupRule.php',
'PhrictionReplyHandler' => 'applications/phriction/mail/PhrictionReplyHandler.php',
'PhrictionSchemaSpec' => 'applications/phriction/storage/PhrictionSchemaSpec.php',
@ -11144,6 +11146,7 @@ phutil_register_library_map(array(
'PhrictionDocumentPHIDType' => 'PhabricatorPHIDType',
'PhrictionDocumentPathHeraldField' => 'PhrictionDocumentHeraldField',
'PhrictionDocumentPolicyCodex' => 'PhabricatorPolicyCodex',
'PhrictionDocumentPublishTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhrictionDocumentSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'PhrictionDocumentSearchEngine' => 'PhabricatorApplicationSearchEngine',
@ -11161,6 +11164,7 @@ phutil_register_library_map(array(
'PhrictionMarkupPreviewController' => 'PhabricatorController',
'PhrictionMoveController' => 'PhrictionController',
'PhrictionNewController' => 'PhrictionController',
'PhrictionPublishController' => 'PhrictionController',
'PhrictionRemarkupRule' => 'PhutilRemarkupRule',
'PhrictionReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'PhrictionSchemaSpec' => 'PhabricatorConfigSchemaSpec',

View file

@ -56,6 +56,8 @@ final class PhabricatorPhrictionApplication extends PhabricatorApplication {
'edit/(?:(?P<id>[1-9]\d*)/)?' => 'PhrictionEditController',
'delete/(?P<id>[1-9]\d*)/' => 'PhrictionDeleteController',
'publish/(?P<documentID>[1-9]\d*)/(?P<contentID>[1-9]\d*)/'
=> 'PhrictionPublishController',
'new/' => 'PhrictionNewController',
'move/(?P<id>[1-9]\d*)/' => 'PhrictionMoveController',

View file

@ -203,7 +203,7 @@ final class PhrictionDocumentController
$curtain = null;
if ($document->getID()) {
$curtain = $this->buildCurtain($document);
$curtain = $this->buildCurtain($document, $content);
}
$crumbs = $this->buildApplicationCrumbs();
@ -230,11 +230,11 @@ final class PhrictionDocumentController
$prop_list = phutil_tag_div('phui-document-view-pro-box', $prop_list);
$page_content = id(new PHUIDocumentView())
->setBanner($version_note)
->setHeader($header)
->setToc($toc)
->appendChild(
array(
$version_note,
$move_notice,
$core_content,
));
@ -277,7 +277,9 @@ final class PhrictionDocumentController
return $view;
}
private function buildCurtain(PhrictionDocument $document) {
private function buildCurtain(
PhrictionDocument $document,
PhrictionContent $content) {
$viewer = $this->getViewer();
$can_edit = PhabricatorPolicyFilter::hasCapability(
@ -286,6 +288,7 @@ final class PhrictionDocumentController
PhabricatorPolicyCapability::CAN_EDIT);
$slug = PhabricatorSlug::normalize($this->slug);
$id = $document->getID();
$curtain = $this->newCurtainView($document);
@ -296,6 +299,26 @@ final class PhrictionDocumentController
->setIcon('fa-pencil')
->setHref('/phriction/edit/'.$document->getID().'/'));
$is_current = false;
$content_id = null;
if ($content) {
if ($content->getPHID() == $document->getContentPHID()) {
$is_current = true;
}
$content_id = $content->getID();
}
$can_publish = ($can_edit && $content && !$is_current);
$publish_uri = "/phriction/publish/{$id}/{$content_id}/";
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Publish'))
->setIcon('fa-upload')
->setDisabled(!$can_publish)
->setWorkflow(true)
->setHref($publish_uri));
if ($document->getStatus() == PhrictionDocumentStatus::STATUS_EXISTS) {
$curtain->addAction(
id(new PhabricatorActionView())

View file

@ -0,0 +1,86 @@
<?php
final class PhrictionPublishController
extends PhrictionController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('documentID');
$content_id = $request->getURIData('contentID');
$document = id(new PhrictionDocumentQuery())
->setViewer($viewer)
->withIDs(array($id))
->needContent(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_EDIT,
PhabricatorPolicyCapability::CAN_VIEW,
))
->executeOne();
if (!$document) {
return new Aphront404Response();
}
$document_uri = $document->getURI();
$content = id(new PhrictionContentQuery())
->setViewer($viewer)
->withIDs(array($content_id))
->executeOne();
if (!$content) {
return new Aphront404Response();
}
if ($content->getPHID() == $document->getContentPHID()) {
return $this->newDialog()
->setTitle(pht('Already Published'))
->appendChild(
pht(
'This version of the document is already the published '.
'version.'))
->addCancelButton($document_uri);
}
$content_uri = $document_uri.'?v='.$content->getVersion();
if ($request->isFormPost()) {
$xactions = array();
$xactions[] = id(new PhrictionTransaction())
->setTransactionType(
PhrictionDocumentPublishTransaction::TRANSACTIONTYPE)
->setNewValue($content->getPHID());
id(new PhrictionTransactionEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true)
->applyTransactions($document, $xactions);
return id(new AphrontRedirectResponse())->setURI($document_uri);
}
if ($content->getVersion() < $document->getContent()->getVersion()) {
$title = pht('Revert Document?');
$body = pht(
'Revert the published version of this document to an older '.
'version?');
$button = pht('Revert');
} else {
$title = pht('Publish Draft?');
$body = pht(
'Update the published version of this document to this newer '.
'version?');
$button = pht('Publish');
}
return $this->newDialog()
->setTitle($title)
->appendChild($body)
->addSubmitButton($button)
->addCancelButton($content_uri);
}
}

View file

@ -0,0 +1,71 @@
<?php
final class PhrictionDocumentPublishTransaction
extends PhrictionDocumentTransactionType {
const TRANSACTIONTYPE = 'publish';
public function generateOldValue($object) {
return $object->getContentPHID();
}
public function applyInternalEffects($object, $value) {
$object->setContentPHID($value);
}
public function getActionName() {
return pht('Published');
}
public function getTitle() {
return pht(
'%s published a new version of this document.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s published a new version of %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function validateTransactions($object, array $xactions) {
$actor = $this->getActor();
$errors = array();
foreach ($xactions as $xaction) {
$content_phid = $xaction->getNewValue();
// If this isn't changing anything, skip it.
if ($content_phid === $object->getContentPHID()) {
continue;
}
$content = id(new PhrictionContentQuery())
->setViewer($actor)
->withPHIDs(array($content_phid))
->executeOne();
if (!$content) {
$errors[] = $this->newInvalidError(
pht(
'Unable to load Content object with PHID "%s".',
$content_phid),
$xaction);
continue;
}
if ($content->getDocumentPHID() !== $object->getPHID()) {
$errors[] = $this->newInvalidError(
pht(
'Content object "%s" can not be published because it belongs '.
'to a different document.',
$content_phid));
continue;
}
}
return $errors;
}
}

View file

@ -9,6 +9,7 @@ final class PHUIDocumentView extends AphrontTagView {
private $toc;
private $foot;
private $curtain;
private $banner;
public function setHeader(PHUIHeaderView $header) {
$header->setTall(true);
@ -46,6 +47,15 @@ final class PHUIDocumentView extends AphrontTagView {
return $this->curtain;
}
public function setBanner($banner) {
$this->banner = $banner;
return $this;
}
public function getBanner() {
return $this->banner;
}
protected function getTagAttributes() {
$classes = array();
@ -160,6 +170,7 @@ final class PHUIDocumentView extends AphrontTagView {
array(
$table_of_contents,
$this->header,
$this->banner,
array(
$curtain,
$main_content,