mirror of
https://we.phorge.it/source/phorge.git
synced 2025-03-28 04:00:17 +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/layout/phabricator-source-code-view.css' => '2ceee894',
|
||||||
'rsrc/css/phui/calendar/phui-calendar-day.css' => '3b4a65d8',
|
'rsrc/css/phui/calendar/phui-calendar-day.css' => '3b4a65d8',
|
||||||
'rsrc/css/phui/calendar/phui-calendar-list.css' => '840baa8d',
|
'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/calendar/phui-calendar.css' => '8345be98',
|
||||||
'rsrc/css/phui/phui-action-header-view.css' => '89c497e7',
|
'rsrc/css/phui/phui-action-header-view.css' => '89c497e7',
|
||||||
'rsrc/css/phui/phui-action-list.css' => '4f4d09f2',
|
'rsrc/css/phui/phui-action-list.css' => '4f4d09f2',
|
||||||
|
@ -763,7 +763,7 @@ return array(
|
||||||
'phui-calendar-css' => '8345be98',
|
'phui-calendar-css' => '8345be98',
|
||||||
'phui-calendar-day-css' => '3b4a65d8',
|
'phui-calendar-day-css' => '3b4a65d8',
|
||||||
'phui-calendar-list-css' => '840baa8d',
|
'phui-calendar-list-css' => '840baa8d',
|
||||||
'phui-calendar-month-css' => '4fba442e',
|
'phui-calendar-month-css' => 'a6993b38',
|
||||||
'phui-crumbs-view-css' => '594d719e',
|
'phui-crumbs-view-css' => '594d719e',
|
||||||
'phui-document-view-css' => '94d5dcd8',
|
'phui-document-view-css' => '94d5dcd8',
|
||||||
'phui-feed-story-css' => 'c9f3a0b5',
|
'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',
|
'PhamePost' => 'applications/phame/storage/PhamePost.php',
|
||||||
'PhamePostDeleteController' => 'applications/phame/controller/post/PhamePostDeleteController.php',
|
'PhamePostDeleteController' => 'applications/phame/controller/post/PhamePostDeleteController.php',
|
||||||
'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php',
|
'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php',
|
||||||
|
'PhamePostEditor' => 'applications/phame/editor/PhamePostEditor.php',
|
||||||
'PhamePostFramedController' => 'applications/phame/controller/post/PhamePostFramedController.php',
|
'PhamePostFramedController' => 'applications/phame/controller/post/PhamePostFramedController.php',
|
||||||
'PhamePostListController' => 'applications/phame/controller/post/PhamePostListController.php',
|
'PhamePostListController' => 'applications/phame/controller/post/PhamePostListController.php',
|
||||||
'PhamePostNewController' => 'applications/phame/controller/post/PhamePostNewController.php',
|
'PhamePostNewController' => 'applications/phame/controller/post/PhamePostNewController.php',
|
||||||
|
@ -2798,6 +2799,8 @@ phutil_register_library_map(array(
|
||||||
'PhamePostPreviewController' => 'applications/phame/controller/post/PhamePostPreviewController.php',
|
'PhamePostPreviewController' => 'applications/phame/controller/post/PhamePostPreviewController.php',
|
||||||
'PhamePostPublishController' => 'applications/phame/controller/post/PhamePostPublishController.php',
|
'PhamePostPublishController' => 'applications/phame/controller/post/PhamePostPublishController.php',
|
||||||
'PhamePostQuery' => 'applications/phame/query/PhamePostQuery.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',
|
'PhamePostUnpublishController' => 'applications/phame/controller/post/PhamePostUnpublishController.php',
|
||||||
'PhamePostView' => 'applications/phame/view/PhamePostView.php',
|
'PhamePostView' => 'applications/phame/view/PhamePostView.php',
|
||||||
'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php',
|
'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php',
|
||||||
|
@ -6269,10 +6272,12 @@ phutil_register_library_map(array(
|
||||||
'PhameDAO',
|
'PhameDAO',
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
'PhabricatorMarkupInterface',
|
'PhabricatorMarkupInterface',
|
||||||
|
'PhabricatorApplicationTransactionInterface',
|
||||||
'PhabricatorTokenReceiverInterface',
|
'PhabricatorTokenReceiverInterface',
|
||||||
),
|
),
|
||||||
'PhamePostDeleteController' => 'PhameController',
|
'PhamePostDeleteController' => 'PhameController',
|
||||||
'PhamePostEditController' => 'PhameController',
|
'PhamePostEditController' => 'PhameController',
|
||||||
|
'PhamePostEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
'PhamePostFramedController' => 'PhameController',
|
'PhamePostFramedController' => 'PhameController',
|
||||||
'PhamePostListController' => 'PhameController',
|
'PhamePostListController' => 'PhameController',
|
||||||
'PhamePostNewController' => 'PhameController',
|
'PhamePostNewController' => 'PhameController',
|
||||||
|
@ -6280,6 +6285,8 @@ phutil_register_library_map(array(
|
||||||
'PhamePostPreviewController' => 'PhameController',
|
'PhamePostPreviewController' => 'PhameController',
|
||||||
'PhamePostPublishController' => 'PhameController',
|
'PhamePostPublishController' => 'PhameController',
|
||||||
'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhamePostTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
|
'PhamePostTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'PhamePostUnpublishController' => 'PhameController',
|
'PhamePostUnpublishController' => 'PhameController',
|
||||||
'PhamePostView' => 'AphrontView',
|
'PhamePostView' => 'AphrontView',
|
||||||
'PhamePostViewController' => 'PhameController',
|
'PhamePostViewController' => 'PhameController',
|
||||||
|
|
|
@ -2,19 +2,12 @@
|
||||||
|
|
||||||
final class PhamePostDeleteController extends PhameController {
|
final class PhamePostDeleteController extends PhameController {
|
||||||
|
|
||||||
private $id;
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->id = $data['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
|
|
||||||
$post = id(new PhamePostQuery())
|
$post = id(new PhamePostQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($request->getURIData('id')))
|
||||||
->requireCapabilities(
|
->requireCapabilities(
|
||||||
array(
|
array(
|
||||||
PhabricatorPolicyCapability::CAN_EDIT,
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
|
|
@ -2,20 +2,14 @@
|
||||||
|
|
||||||
final class PhamePostEditController extends PhameController {
|
final class PhamePostEditController extends PhameController {
|
||||||
|
|
||||||
private $id;
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$user = $request->getUser();
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
if ($id) {
|
||||||
$this->id = idx($data, 'id');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
|
||||||
|
|
||||||
if ($this->id) {
|
|
||||||
$post = id(new PhamePostQuery())
|
$post = id(new PhamePostQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($id))
|
||||||
->requireCapabilities(
|
->requireCapabilities(
|
||||||
array(
|
array(
|
||||||
PhabricatorPolicyCapability::CAN_EDIT,
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
@ -25,7 +19,7 @@ final class PhamePostEditController extends PhameController {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
$cancel_uri = $this->getApplicationURI('/post/view/'.$this->id.'/');
|
$cancel_uri = $this->getApplicationURI('/post/view/'.$id.'/');
|
||||||
$submit_button = pht('Save Changes');
|
$submit_button = pht('Save Changes');
|
||||||
$page_title = pht('Edit Post');
|
$page_title = pht('Edit Post');
|
||||||
} else {
|
} else {
|
||||||
|
@ -49,44 +43,52 @@ final class PhamePostEditController extends PhameController {
|
||||||
$page_title = pht('Create Post');
|
$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;
|
$e_title = true;
|
||||||
$errors = array();
|
$e_phame_title = true;
|
||||||
|
$validation_exception = null;
|
||||||
if ($request->isFormPost()) {
|
if ($request->isFormPost()) {
|
||||||
$comments = $request->getStr('comments_widget');
|
$title = $request->getStr('title');
|
||||||
$data = array('comments_widget' => $comments);
|
$phame_title = $request->getStr('phame_title');
|
||||||
$phame_title = $request->getStr('phame_title');
|
$phame_title = PhabricatorSlug::normalize($phame_title);
|
||||||
$phame_title = PhabricatorSlug::normalize($phame_title);
|
$body = $request->getStr('body');
|
||||||
$title = $request->getStr('title');
|
$comments_widget = $request->getStr('comments_widget');
|
||||||
$post->setTitle($title);
|
|
||||||
$post->setPhameTitle($phame_title);
|
|
||||||
$post->setBody($request->getStr('body'));
|
|
||||||
$post->setConfigData($data);
|
|
||||||
|
|
||||||
if ($phame_title == '/') {
|
$xactions = array(
|
||||||
$errors[] = pht('Phame title must be nonempty.');
|
id(new PhamePostTransaction())
|
||||||
$e_phame_title = pht('Required');
|
->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)) {
|
$editor = id(new PhamePostEditor())
|
||||||
$errors[] = pht('Title must be nonempty.');
|
->setActor($user)
|
||||||
$e_title = pht('Required');
|
->setContentSourceFromRequest($request)
|
||||||
} else {
|
->setContinueOnNoEffect(true);
|
||||||
$e_title = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$errors) {
|
try {
|
||||||
try {
|
$editor->applyTransactions($post, $xactions);
|
||||||
$post->save();
|
|
||||||
|
|
||||||
$uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
|
$uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
|
||||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||||
} catch (AphrontDuplicateKeyQueryException $e) {
|
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||||
$e_phame_title = pht('Not Unique');
|
$validation_exception = $ex;
|
||||||
$errors[] = pht('Another post already uses this slug. '.
|
$e_title = $validation_exception->getShortMessage(
|
||||||
'Each post must have a unique slug.');
|
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())
|
id(new AphrontFormTextControl())
|
||||||
->setLabel(pht('Title'))
|
->setLabel(pht('Title'))
|
||||||
->setName('title')
|
->setName('title')
|
||||||
->setValue($post->getTitle())
|
->setValue($title)
|
||||||
->setID('post-title')
|
->setID('post-title')
|
||||||
->setError($e_title))
|
->setError($e_title))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormTextControl())
|
id(new AphrontFormTextControl())
|
||||||
->setLabel(pht('Phame Title'))
|
->setLabel(pht('Phame Title'))
|
||||||
->setName('phame_title')
|
->setName('phame_title')
|
||||||
->setValue(rtrim($post->getPhameTitle(), '/'))
|
->setValue(rtrim($phame_title, '/'))
|
||||||
->setID('post-phame-title')
|
->setID('post-phame-title')
|
||||||
->setCaption(pht('Up to 64 alphanumeric characters '.
|
->setCaption(pht('Up to 64 alphanumeric characters '.
|
||||||
'with underscores for spaces. '.
|
'with underscores for spaces. '.
|
||||||
|
@ -123,7 +125,7 @@ final class PhamePostEditController extends PhameController {
|
||||||
id(new PhabricatorRemarkupControl())
|
id(new PhabricatorRemarkupControl())
|
||||||
->setLabel(pht('Body'))
|
->setLabel(pht('Body'))
|
||||||
->setName('body')
|
->setName('body')
|
||||||
->setValue($post->getBody())
|
->setValue($body)
|
||||||
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
||||||
->setID('post-body')
|
->setID('post-body')
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
|
@ -132,7 +134,7 @@ final class PhamePostEditController extends PhameController {
|
||||||
id(new AphrontFormSelectControl())
|
id(new AphrontFormSelectControl())
|
||||||
->setLabel(pht('Comments Widget'))
|
->setLabel(pht('Comments Widget'))
|
||||||
->setName('comments_widget')
|
->setName('comments_widget')
|
||||||
->setvalue($post->getCommentsWidget())
|
->setvalue($comments_widget)
|
||||||
->setOptions($post->getCommentsWidgetOptionsForSelect()))
|
->setOptions($post->getCommentsWidgetOptionsForSelect()))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
|
@ -161,13 +163,13 @@ final class PhamePostEditController extends PhameController {
|
||||||
|
|
||||||
$form_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($page_title)
|
->setHeaderText($page_title)
|
||||||
->setFormErrors($errors)
|
->setValidationException($validation_exception)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(
|
$crumbs->addTextCrumb(
|
||||||
$page_title,
|
$page_title,
|
||||||
$this->getApplicationURI('/post/view/'.$this->id.'/'));
|
$this->getApplicationURI('/post/view/'.$id.'/'));
|
||||||
|
|
||||||
$nav = $this->renderSideNavFilterView(null);
|
$nav = $this->renderSideNavFilterView(null);
|
||||||
$nav->appendChild(
|
$nav->appendChild(
|
||||||
|
|
|
@ -2,22 +2,16 @@
|
||||||
|
|
||||||
final class PhamePostNewController extends PhameController {
|
final class PhamePostNewController extends PhameController {
|
||||||
|
|
||||||
private $id;
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->id = idx($data, 'id');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
|
||||||
$post = null;
|
$post = null;
|
||||||
$view_uri = null;
|
$view_uri = null;
|
||||||
if ($this->id) {
|
if ($id) {
|
||||||
$post = id(new PhamePostQuery())
|
$post = id(new PhamePostQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($id))
|
||||||
->requireCapabilities(
|
->requireCapabilities(
|
||||||
array(
|
array(
|
||||||
PhabricatorPolicyCapability::CAN_EDIT,
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
|
|
@ -2,19 +2,12 @@
|
||||||
|
|
||||||
final class PhamePostViewController extends PhameController {
|
final class PhamePostViewController extends PhameController {
|
||||||
|
|
||||||
private $id;
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->id = $data['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
|
|
||||||
$post = id(new PhamePostQuery())
|
$post = id(new PhamePostQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($request->getURIData('id')))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
|
||||||
if (!$post) {
|
if (!$post) {
|
||||||
|
@ -65,7 +58,10 @@ final class PhamePostViewController extends PhameController {
|
||||||
$nav->appendChild(
|
$nav->appendChild(
|
||||||
array(
|
array(
|
||||||
$object_box,
|
$object_box,
|
||||||
));
|
$this->buildTransactionTimeline(
|
||||||
|
$post,
|
||||||
|
new PhamePostTransactionQuery()),
|
||||||
|
));
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
return $this->buildApplicationPage(
|
||||||
$nav,
|
$nav,
|
||||||
|
@ -78,10 +74,10 @@ final class PhamePostViewController extends PhameController {
|
||||||
PhamePost $post,
|
PhamePost $post,
|
||||||
PhabricatorUser $user) {
|
PhabricatorUser $user) {
|
||||||
|
|
||||||
$actions = id(new PhabricatorActionListView())
|
$actions = id(new PhabricatorActionListView())
|
||||||
->setObject($post)
|
->setObject($post)
|
||||||
->setObjectURI($this->getRequest()->getRequestURI())
|
->setObjectURI($this->getRequest()->getRequestURI())
|
||||||
->setUser($user);
|
->setUser($user);
|
||||||
|
|
||||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
$user,
|
$user,
|
||||||
|
|
|
@ -76,8 +76,6 @@ final class PhameBlogEditor
|
||||||
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
||||||
$object->setJoinPolicy($xaction->getNewValue());
|
$object->setJoinPolicy($xaction->getNewValue());
|
||||||
return;
|
return;
|
||||||
case PhabricatorTransactions::TYPE_COMMENT:
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||||
|
@ -95,7 +93,6 @@ final class PhameBlogEditor
|
||||||
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
||||||
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
||||||
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
||||||
case PhabricatorTransactions::TYPE_COMMENT:
|
|
||||||
return;
|
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
|
implements
|
||||||
PhabricatorPolicyInterface,
|
PhabricatorPolicyInterface,
|
||||||
PhabricatorMarkupInterface,
|
PhabricatorMarkupInterface,
|
||||||
|
PhabricatorApplicationTransactionInterface,
|
||||||
PhabricatorTokenReceiverInterface {
|
PhabricatorTokenReceiverInterface {
|
||||||
|
|
||||||
const MARKUP_FIELD_BODY = 'markup:body';
|
const MARKUP_FIELD_BODY = 'markup:body';
|
||||||
|
@ -74,6 +75,12 @@ final class PhamePost extends PhameDAO
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setCommentsWidget($widget) {
|
||||||
|
$config_data = $this->getConfigData();
|
||||||
|
$config_data['comments_widget'] = $widget;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getCommentsWidget() {
|
public function getCommentsWidget() {
|
||||||
$config_data = $this->getConfigData();
|
$config_data = $this->getConfigData();
|
||||||
if (empty($config_data)) {
|
if (empty($config_data)) {
|
||||||
|
@ -181,7 +188,6 @@ final class PhamePost extends PhameDAO
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getPolicy($capability) {
|
public function getPolicy($capability) {
|
||||||
// Draft posts are visible only to the author. Published posts are visible
|
// Draft posts are visible only to the author. Published posts are visible
|
||||||
// to whoever the blog is visible to.
|
// to whoever the blog is visible to.
|
||||||
|
@ -199,7 +205,6 @@ final class PhamePost extends PhameDAO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
|
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
|
||||||
// A blog post's author can always view it, and is the only user allowed
|
// A blog post's author can always view it, and is the only user allowed
|
||||||
// to edit it.
|
// to edit it.
|
||||||
|
@ -211,7 +216,6 @@ final class PhamePost extends PhameDAO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function describeAutomaticCapability($capability) {
|
public function describeAutomaticCapability($capability) {
|
||||||
return pht(
|
return pht(
|
||||||
'The author of a blog post can always view and edit it.');
|
'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;
|
return $this->getPHID().':'.$field.':'.$hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function newMarkupEngine($field) {
|
public function newMarkupEngine($field) {
|
||||||
return PhabricatorMarkupEngine::newPhameMarkupEngine();
|
return PhabricatorMarkupEngine::newPhameMarkupEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getMarkupText($field) {
|
public function getMarkupText($field) {
|
||||||
switch ($field) {
|
switch ($field) {
|
||||||
case self::MARKUP_FIELD_BODY:
|
case self::MARKUP_FIELD_BODY:
|
||||||
|
@ -248,13 +250,37 @@ final class PhamePost extends PhameDAO
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function shouldUseMarkupCache($field) {
|
public function shouldUseMarkupCache($field) {
|
||||||
return (bool)$this->getPHID();
|
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 )---------------------------------- */
|
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
public function getUsersToNotifyOfTokenGiven() {
|
public function getUsersToNotifyOfTokenGiven() {
|
||||||
return array(
|
return array(
|
||||||
$this->getBloggerPHID(),
|
$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…
Add table
Reference in a new issue