mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Phame - move over post creation and edit to use an editor
Summary: This adds the bare minimum transaction set for editing posts. Fixes T7626 because now files will be correctly attached to phame posts on subsequent edits. Future work here should be adding transaction types like `TYPE_BLOG` for when posts are moved between blogs, `TYPE_VISIBILITY` for when posts are moved to published, etc. Nothing too tricky there but keeping this diff relatively small seems prudent. Test Plan: made posts successfully. also made errors like no title, no phame title, and duplicate phame title and got correct errors. added a file to a post and verified file has phame post in "attached" tab, which should fix T7626. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T7626 Differential Revision: https://secure.phabricator.com/D12864
This commit is contained in:
parent
e3134a1d47
commit
b6733e4a86
12 changed files with 490 additions and 94 deletions
|
@ -122,7 +122,7 @@ return array(
|
|||
'rsrc/css/layout/phabricator-source-code-view.css' => '2ceee894',
|
||||
'rsrc/css/phui/calendar/phui-calendar-day.css' => '3b4a65d8',
|
||||
'rsrc/css/phui/calendar/phui-calendar-list.css' => '840baa8d',
|
||||
'rsrc/css/phui/calendar/phui-calendar-month.css' => '4fba442e',
|
||||
'rsrc/css/phui/calendar/phui-calendar-month.css' => 'a6993b38',
|
||||
'rsrc/css/phui/calendar/phui-calendar.css' => '8345be98',
|
||||
'rsrc/css/phui/phui-action-header-view.css' => '89c497e7',
|
||||
'rsrc/css/phui/phui-action-list.css' => '4f4d09f2',
|
||||
|
@ -763,7 +763,7 @@ return array(
|
|||
'phui-calendar-css' => '8345be98',
|
||||
'phui-calendar-day-css' => '3b4a65d8',
|
||||
'phui-calendar-list-css' => '840baa8d',
|
||||
'phui-calendar-month-css' => '4fba442e',
|
||||
'phui-calendar-month-css' => 'a6993b38',
|
||||
'phui-crumbs-view-css' => '594d719e',
|
||||
'phui-document-view-css' => '94d5dcd8',
|
||||
'phui-feed-story-css' => 'c9f3a0b5',
|
||||
|
|
19
resources/sql/autopatches/20150515.phame.post.xaction.sql
Normal file
19
resources/sql/autopatches/20150515.phame.post.xaction.sql
Normal file
|
@ -0,0 +1,19 @@
|
|||
CREATE TABLE {$NAMESPACE}_phame.phame_posttransaction (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
authorPHID VARBINARY(64) NOT NULL,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
viewPolicy VARBINARY(64) NOT NULL,
|
||||
editPolicy VARBINARY(64) NOT NULL,
|
||||
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||
commentVersion INT UNSIGNED NOT NULL,
|
||||
transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||
oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||
newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||
contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||
metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_phid` (`phid`),
|
||||
KEY `key_object` (`objectPHID`)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -2791,6 +2791,7 @@ phutil_register_library_map(array(
|
|||
'PhamePost' => 'applications/phame/storage/PhamePost.php',
|
||||
'PhamePostDeleteController' => 'applications/phame/controller/post/PhamePostDeleteController.php',
|
||||
'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php',
|
||||
'PhamePostEditor' => 'applications/phame/editor/PhamePostEditor.php',
|
||||
'PhamePostFramedController' => 'applications/phame/controller/post/PhamePostFramedController.php',
|
||||
'PhamePostListController' => 'applications/phame/controller/post/PhamePostListController.php',
|
||||
'PhamePostNewController' => 'applications/phame/controller/post/PhamePostNewController.php',
|
||||
|
@ -2798,6 +2799,8 @@ phutil_register_library_map(array(
|
|||
'PhamePostPreviewController' => 'applications/phame/controller/post/PhamePostPreviewController.php',
|
||||
'PhamePostPublishController' => 'applications/phame/controller/post/PhamePostPublishController.php',
|
||||
'PhamePostQuery' => 'applications/phame/query/PhamePostQuery.php',
|
||||
'PhamePostTransaction' => 'applications/phame/storage/PhamePostTransaction.php',
|
||||
'PhamePostTransactionQuery' => 'applications/phame/query/PhamePostTransactionQuery.php',
|
||||
'PhamePostUnpublishController' => 'applications/phame/controller/post/PhamePostUnpublishController.php',
|
||||
'PhamePostView' => 'applications/phame/view/PhamePostView.php',
|
||||
'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php',
|
||||
|
@ -6269,10 +6272,12 @@ phutil_register_library_map(array(
|
|||
'PhameDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorMarkupInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorTokenReceiverInterface',
|
||||
),
|
||||
'PhamePostDeleteController' => 'PhameController',
|
||||
'PhamePostEditController' => 'PhameController',
|
||||
'PhamePostEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhamePostFramedController' => 'PhameController',
|
||||
'PhamePostListController' => 'PhameController',
|
||||
'PhamePostNewController' => 'PhameController',
|
||||
|
@ -6280,6 +6285,8 @@ phutil_register_library_map(array(
|
|||
'PhamePostPreviewController' => 'PhameController',
|
||||
'PhamePostPublishController' => 'PhameController',
|
||||
'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhamePostTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhamePostTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhamePostUnpublishController' => 'PhameController',
|
||||
'PhamePostView' => 'AphrontView',
|
||||
'PhamePostViewController' => 'PhameController',
|
||||
|
|
|
@ -2,19 +2,12 @@
|
|||
|
||||
final class PhamePostDeleteController extends PhameController {
|
||||
|
||||
private $id;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = $data['id'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$user = $request->getUser();
|
||||
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->id))
|
||||
->withIDs(array($request->getURIData('id')))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
|
|
|
@ -2,20 +2,14 @@
|
|||
|
||||
final class PhamePostEditController extends PhameController {
|
||||
|
||||
private $id;
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$user = $request->getUser();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = idx($data, 'id');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
if ($this->id) {
|
||||
if ($id) {
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->id))
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
|
@ -25,7 +19,7 @@ final class PhamePostEditController extends PhameController {
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cancel_uri = $this->getApplicationURI('/post/view/'.$this->id.'/');
|
||||
$cancel_uri = $this->getApplicationURI('/post/view/'.$id.'/');
|
||||
$submit_button = pht('Save Changes');
|
||||
$page_title = pht('Edit Post');
|
||||
} else {
|
||||
|
@ -49,44 +43,52 @@ final class PhamePostEditController extends PhameController {
|
|||
$page_title = pht('Create Post');
|
||||
}
|
||||
|
||||
$e_phame_title = null;
|
||||
$title = $post->getTitle();
|
||||
$phame_title = $post->getPhameTitle();
|
||||
$body = $post->getBody();
|
||||
$comments_widget = $post->getCommentsWidget();
|
||||
|
||||
$e_title = true;
|
||||
$errors = array();
|
||||
|
||||
$e_phame_title = true;
|
||||
$validation_exception = null;
|
||||
if ($request->isFormPost()) {
|
||||
$comments = $request->getStr('comments_widget');
|
||||
$data = array('comments_widget' => $comments);
|
||||
$phame_title = $request->getStr('phame_title');
|
||||
$phame_title = PhabricatorSlug::normalize($phame_title);
|
||||
$title = $request->getStr('title');
|
||||
$post->setTitle($title);
|
||||
$post->setPhameTitle($phame_title);
|
||||
$post->setBody($request->getStr('body'));
|
||||
$post->setConfigData($data);
|
||||
$title = $request->getStr('title');
|
||||
$phame_title = $request->getStr('phame_title');
|
||||
$phame_title = PhabricatorSlug::normalize($phame_title);
|
||||
$body = $request->getStr('body');
|
||||
$comments_widget = $request->getStr('comments_widget');
|
||||
|
||||
if ($phame_title == '/') {
|
||||
$errors[] = pht('Phame title must be nonempty.');
|
||||
$e_phame_title = pht('Required');
|
||||
}
|
||||
$xactions = array(
|
||||
id(new PhamePostTransaction())
|
||||
->setTransactionType(PhamePostTransaction::TYPE_TITLE)
|
||||
->setNewValue($title),
|
||||
id(new PhamePostTransaction())
|
||||
->setTransactionType(PhamePostTransaction::TYPE_PHAME_TITLE)
|
||||
->setNewValue($phame_title),
|
||||
id(new PhamePostTransaction())
|
||||
->setTransactionType(PhamePostTransaction::TYPE_BODY)
|
||||
->setNewValue($body),
|
||||
id(new PhamePostTransaction())
|
||||
->setTransactionType(PhamePostTransaction::TYPE_COMMENTS_WIDGET)
|
||||
->setNewValue($comments_widget),
|
||||
);
|
||||
|
||||
if (!strlen($title)) {
|
||||
$errors[] = pht('Title must be nonempty.');
|
||||
$e_title = pht('Required');
|
||||
} else {
|
||||
$e_title = null;
|
||||
}
|
||||
$editor = id(new PhamePostEditor())
|
||||
->setActor($user)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true);
|
||||
|
||||
if (!$errors) {
|
||||
try {
|
||||
$post->save();
|
||||
try {
|
||||
$editor->applyTransactions($post, $xactions);
|
||||
|
||||
$uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
} catch (AphrontDuplicateKeyQueryException $e) {
|
||||
$e_phame_title = pht('Not Unique');
|
||||
$errors[] = pht('Another post already uses this slug. '.
|
||||
'Each post must have a unique slug.');
|
||||
}
|
||||
$uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||
$validation_exception = $ex;
|
||||
$e_title = $validation_exception->getShortMessage(
|
||||
PhamePostTransaction::TYPE_TITLE);
|
||||
$e_phame_title = $validation_exception->getShortMessage(
|
||||
PhamePostTransaction::TYPE_PHAME_TITLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,14 +108,14 @@ final class PhamePostEditController extends PhameController {
|
|||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Title'))
|
||||
->setName('title')
|
||||
->setValue($post->getTitle())
|
||||
->setValue($title)
|
||||
->setID('post-title')
|
||||
->setError($e_title))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Phame Title'))
|
||||
->setName('phame_title')
|
||||
->setValue(rtrim($post->getPhameTitle(), '/'))
|
||||
->setValue(rtrim($phame_title, '/'))
|
||||
->setID('post-phame-title')
|
||||
->setCaption(pht('Up to 64 alphanumeric characters '.
|
||||
'with underscores for spaces. '.
|
||||
|
@ -123,7 +125,7 @@ final class PhamePostEditController extends PhameController {
|
|||
id(new PhabricatorRemarkupControl())
|
||||
->setLabel(pht('Body'))
|
||||
->setName('body')
|
||||
->setValue($post->getBody())
|
||||
->setValue($body)
|
||||
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
||||
->setID('post-body')
|
||||
->setUser($user)
|
||||
|
@ -132,7 +134,7 @@ final class PhamePostEditController extends PhameController {
|
|||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Comments Widget'))
|
||||
->setName('comments_widget')
|
||||
->setvalue($post->getCommentsWidget())
|
||||
->setvalue($comments_widget)
|
||||
->setOptions($post->getCommentsWidgetOptionsForSelect()))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
|
@ -161,13 +163,13 @@ final class PhamePostEditController extends PhameController {
|
|||
|
||||
$form_box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($page_title)
|
||||
->setFormErrors($errors)
|
||||
->setValidationException($validation_exception)
|
||||
->setForm($form);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
$page_title,
|
||||
$this->getApplicationURI('/post/view/'.$this->id.'/'));
|
||||
$this->getApplicationURI('/post/view/'.$id.'/'));
|
||||
|
||||
$nav = $this->renderSideNavFilterView(null);
|
||||
$nav->appendChild(
|
||||
|
|
|
@ -2,22 +2,16 @@
|
|||
|
||||
final class PhamePostNewController extends PhameController {
|
||||
|
||||
private $id;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = idx($data, 'id');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$user = $request->getUser();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$post = null;
|
||||
$view_uri = null;
|
||||
if ($this->id) {
|
||||
if ($id) {
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->id))
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
|
|
|
@ -2,19 +2,12 @@
|
|||
|
||||
final class PhamePostViewController extends PhameController {
|
||||
|
||||
private $id;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = $data['id'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$user = $request->getUser();
|
||||
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->id))
|
||||
->withIDs(array($request->getURIData('id')))
|
||||
->executeOne();
|
||||
|
||||
if (!$post) {
|
||||
|
@ -65,7 +58,10 @@ final class PhamePostViewController extends PhameController {
|
|||
$nav->appendChild(
|
||||
array(
|
||||
$object_box,
|
||||
));
|
||||
$this->buildTransactionTimeline(
|
||||
$post,
|
||||
new PhamePostTransactionQuery()),
|
||||
));
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
$nav,
|
||||
|
@ -78,10 +74,10 @@ final class PhamePostViewController extends PhameController {
|
|||
PhamePost $post,
|
||||
PhabricatorUser $user) {
|
||||
|
||||
$actions = id(new PhabricatorActionListView())
|
||||
->setObject($post)
|
||||
->setObjectURI($this->getRequest()->getRequestURI())
|
||||
->setUser($user);
|
||||
$actions = id(new PhabricatorActionListView())
|
||||
->setObject($post)
|
||||
->setObjectURI($this->getRequest()->getRequestURI())
|
||||
->setUser($user);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$user,
|
||||
|
|
|
@ -76,8 +76,6 @@ final class PhameBlogEditor
|
|||
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
||||
$object->setJoinPolicy($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorTransactions::TYPE_COMMENT:
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
|
@ -95,7 +93,6 @@ final class PhameBlogEditor
|
|||
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
||||
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
||||
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
||||
case PhabricatorTransactions::TYPE_COMMENT:
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
165
src/applications/phame/editor/PhamePostEditor.php
Normal file
165
src/applications/phame/editor/PhamePostEditor.php
Normal file
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
final class PhamePostEditor
|
||||
extends PhabricatorApplicationTransactionEditor {
|
||||
|
||||
public function getEditorApplicationClass() {
|
||||
return 'PhabricatorPhameApplication';
|
||||
}
|
||||
|
||||
public function getEditorObjectsDescription() {
|
||||
return pht('Blog Posts');
|
||||
}
|
||||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
$types[] = PhamePostTransaction::TYPE_TITLE;
|
||||
$types[] = PhamePostTransaction::TYPE_PHAME_TITLE;
|
||||
$types[] = PhamePostTransaction::TYPE_BODY;
|
||||
$types[] = PhamePostTransaction::TYPE_COMMENTS_WIDGET;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
protected function getCustomTransactionOldValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhamePostTransaction::TYPE_TITLE:
|
||||
return $object->getTitle();
|
||||
case PhamePostTransaction::TYPE_PHAME_TITLE:
|
||||
return $object->getPhameTitle();
|
||||
case PhamePostTransaction::TYPE_BODY:
|
||||
return $object->getBody();
|
||||
case PhamePostTransaction::TYPE_COMMENTS_WIDGET:
|
||||
return $object->getCommentsWidget();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getCustomTransactionNewValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhamePostTransaction::TYPE_TITLE:
|
||||
case PhamePostTransaction::TYPE_PHAME_TITLE:
|
||||
case PhamePostTransaction::TYPE_BODY:
|
||||
case PhamePostTransaction::TYPE_COMMENTS_WIDGET:
|
||||
return $xaction->getNewValue();
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyCustomInternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhamePostTransaction::TYPE_TITLE:
|
||||
return $object->setTitle($xaction->getNewValue());
|
||||
case PhamePostTransaction::TYPE_PHAME_TITLE:
|
||||
return $object->setPhameTitle($xaction->getNewValue());
|
||||
case PhamePostTransaction::TYPE_BODY:
|
||||
return $object->setBody($xaction->getNewValue());
|
||||
case PhamePostTransaction::TYPE_COMMENTS_WIDGET:
|
||||
return $object->setCommentsWidget($xaction->getNewValue());
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomExternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhamePostTransaction::TYPE_TITLE:
|
||||
case PhamePostTransaction::TYPE_PHAME_TITLE:
|
||||
case PhamePostTransaction::TYPE_BODY:
|
||||
case PhamePostTransaction::TYPE_COMMENTS_WIDGET:
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function validateTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
$type,
|
||||
array $xactions) {
|
||||
|
||||
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||
|
||||
switch ($type) {
|
||||
case PhamePostTransaction::TYPE_TITLE:
|
||||
$missing = $this->validateIsEmptyTextField(
|
||||
$object->getTitle(),
|
||||
$xactions);
|
||||
|
||||
if ($missing) {
|
||||
$error = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Required'),
|
||||
pht('Title is required.'),
|
||||
nonempty(last($xactions), null));
|
||||
|
||||
$error->setIsMissingFieldError(true);
|
||||
$errors[] = $error;
|
||||
}
|
||||
break;
|
||||
case PhamePostTransaction::TYPE_PHAME_TITLE:
|
||||
$missing = $this->validateIsEmptyTextField(
|
||||
$object->getPhameTitle(),
|
||||
$xactions);
|
||||
$phame_title = last($xactions)->getNewValue();
|
||||
|
||||
if ($missing || $phame_title == '/') {
|
||||
$error = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Required'),
|
||||
pht('Phame title is required.'),
|
||||
nonempty(last($xactions), null));
|
||||
|
||||
$error->setIsMissingFieldError(true);
|
||||
$errors[] = $error;
|
||||
}
|
||||
|
||||
$duplicate_post = id(new PhamePostQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withPhameTitles(array($phame_title))
|
||||
->executeOne();
|
||||
if ($duplicate_post && $duplicate_post->getID() != $object->getID()) {
|
||||
$error_text = pht(
|
||||
'Phame title must be unique; another post already has this phame '.
|
||||
'title.');
|
||||
$error = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Not Unique'),
|
||||
$error_text,
|
||||
nonempty(last($xactions), null));
|
||||
$errors[] = $error;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
protected function shouldSendMail(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function shouldPublishFeedStory(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function supportsSearch() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
10
src/applications/phame/query/PhamePostTransactionQuery.php
Normal file
10
src/applications/phame/query/PhamePostTransactionQuery.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
final class PhamePostTransactionQuery
|
||||
extends PhabricatorApplicationTransactionQuery {
|
||||
|
||||
public function getTemplateApplicationTransaction() {
|
||||
return new PhamePostTransaction();
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ final class PhamePost extends PhameDAO
|
|||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorMarkupInterface,
|
||||
PhabricatorApplicationTransactionInterface,
|
||||
PhabricatorTokenReceiverInterface {
|
||||
|
||||
const MARKUP_FIELD_BODY = 'markup:body';
|
||||
|
@ -74,6 +75,12 @@ final class PhamePost extends PhameDAO
|
|||
return $name;
|
||||
}
|
||||
|
||||
public function setCommentsWidget($widget) {
|
||||
$config_data = $this->getConfigData();
|
||||
$config_data['comments_widget'] = $widget;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCommentsWidget() {
|
||||
$config_data = $this->getConfigData();
|
||||
if (empty($config_data)) {
|
||||
|
@ -181,7 +188,6 @@ final class PhamePost extends PhameDAO
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
public function getPolicy($capability) {
|
||||
// Draft posts are visible only to the author. Published posts are visible
|
||||
// to whoever the blog is visible to.
|
||||
|
@ -199,7 +205,6 @@ final class PhamePost extends PhameDAO
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
|
||||
// A blog post's author can always view it, and is the only user allowed
|
||||
// to edit it.
|
||||
|
@ -211,7 +216,6 @@ final class PhamePost extends PhameDAO
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return pht(
|
||||
'The author of a blog post can always view and edit it.');
|
||||
|
@ -226,12 +230,10 @@ final class PhamePost extends PhameDAO
|
|||
return $this->getPHID().':'.$field.':'.$hash;
|
||||
}
|
||||
|
||||
|
||||
public function newMarkupEngine($field) {
|
||||
return PhabricatorMarkupEngine::newPhameMarkupEngine();
|
||||
}
|
||||
|
||||
|
||||
public function getMarkupText($field) {
|
||||
switch ($field) {
|
||||
case self::MARKUP_FIELD_BODY:
|
||||
|
@ -248,13 +250,37 @@ final class PhamePost extends PhameDAO
|
|||
return $output;
|
||||
}
|
||||
|
||||
|
||||
public function shouldUseMarkupCache($field) {
|
||||
return (bool)$this->getPHID();
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
||||
public function getApplicationTransactionEditor() {
|
||||
return new PhamePostEditor();
|
||||
}
|
||||
|
||||
public function getApplicationTransactionObject() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApplicationTransactionTemplate() {
|
||||
return new PhamePostTransaction();
|
||||
}
|
||||
|
||||
public function willRenderTimeline(
|
||||
PhabricatorApplicationTransactionView $timeline,
|
||||
AphrontRequest $request) {
|
||||
|
||||
return $timeline;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */
|
||||
|
||||
|
||||
public function getUsersToNotifyOfTokenGiven() {
|
||||
return array(
|
||||
$this->getBloggerPHID(),
|
||||
|
|
187
src/applications/phame/storage/PhamePostTransaction.php
Normal file
187
src/applications/phame/storage/PhamePostTransaction.php
Normal file
|
@ -0,0 +1,187 @@
|
|||
<?php
|
||||
|
||||
final class PhamePostTransaction
|
||||
extends PhabricatorApplicationTransaction {
|
||||
|
||||
const TYPE_TITLE = 'phame.post.title';
|
||||
const TYPE_PHAME_TITLE = 'phame.post.phame.title';
|
||||
const TYPE_BODY = 'phame.post.body';
|
||||
const TYPE_COMMENTS_WIDGET = 'phame.post.comments.widget';
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'phame';
|
||||
}
|
||||
|
||||
public function getApplicationTransactionType() {
|
||||
return PhabricatorPhamePostPHIDType::TYPECONST;
|
||||
}
|
||||
|
||||
public function getRemarkupBlocks() {
|
||||
$blocks = parent::getRemarkupBlocks();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_BODY:
|
||||
$blocks[] = $this->getNewValue();
|
||||
break;
|
||||
}
|
||||
|
||||
return $blocks;
|
||||
}
|
||||
|
||||
public function shouldHide() {
|
||||
$old = $this->getOldValue();
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_PHAME_TITLE:
|
||||
case self::TYPE_BODY:
|
||||
return ($old === null);
|
||||
}
|
||||
return parent::shouldHide();
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
$old = $this->getOldValue();
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_TITLE:
|
||||
if ($old === null) {
|
||||
return 'fa-plus';
|
||||
} else {
|
||||
return 'fa-pencil';
|
||||
}
|
||||
break;
|
||||
case self::TYPE_PHAME_TITLE:
|
||||
case self::TYPE_BODY:
|
||||
case self::TYPE_COMMENTS_WIDGET:
|
||||
return 'fa-pencil';
|
||||
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 self::TYPE_TITLE:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created this post.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s updated the post\'s name to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$new);
|
||||
}
|
||||
break;
|
||||
case self::TYPE_BODY:
|
||||
return pht(
|
||||
'%s updated the post\'s body.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
case self::TYPE_PHAME_TITLE:
|
||||
return pht(
|
||||
'%s updated the post\'s phame title to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
rtrim($new, '/'));
|
||||
break;
|
||||
case self::TYPE_COMMENTS_WIDGET:
|
||||
return pht(
|
||||
'%s updated the post\'s comment widget to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$new);
|
||||
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 self::TYPE_TITLE:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s updated the name for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
}
|
||||
break;
|
||||
case self::TYPE_BODY:
|
||||
return pht(
|
||||
'%s updated the body for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case self::TYPE_PHAME_TITLE:
|
||||
return pht(
|
||||
'%s updated the phame title for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case self::TYPE_COMMENTS_WIDGET:
|
||||
return pht(
|
||||
'%s updated the comments widget for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::getTitleForFeed();
|
||||
}
|
||||
|
||||
public function getColor() {
|
||||
$old = $this->getOldValue();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_TITLE:
|
||||
if ($old === null) {
|
||||
return PhabricatorTransactions::COLOR_GREEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::getColor();
|
||||
}
|
||||
|
||||
|
||||
public function hasChangeDetails() {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_BODY:
|
||||
return ($this->getOldValue() !== null);
|
||||
}
|
||||
|
||||
return parent::hasChangeDetails();
|
||||
}
|
||||
|
||||
public function renderChangeDetails(PhabricatorUser $viewer) {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_BODY:
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
return $this->renderTextCorpusChangeDetails(
|
||||
$viewer,
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
|
||||
return parent::renderChangeDetails($viewer);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue