mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
Phame - move over blog create + edit to transactions + editor
Summary: Ref T7626. Modernizes the code a bit here so we can eventually make progress on T7626 and other stuff. Test Plan: made a blog, edited a blog, made errors - stuff looked good Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T7626 Differential Revision: https://secure.phabricator.com/D12849
This commit is contained in:
parent
705c1e6498
commit
f16dda288d
11 changed files with 481 additions and 139 deletions
19
resources/sql/autopatches/20150514.phame.blog.xaction.sql
Normal file
19
resources/sql/autopatches/20150514.phame.blog.xaction.sql
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phame.phame_blogtransaction (
|
||||||
|
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};
|
|
@ -2775,11 +2775,13 @@ phutil_register_library_map(array(
|
||||||
'PhameBlog' => 'applications/phame/storage/PhameBlog.php',
|
'PhameBlog' => 'applications/phame/storage/PhameBlog.php',
|
||||||
'PhameBlogDeleteController' => 'applications/phame/controller/blog/PhameBlogDeleteController.php',
|
'PhameBlogDeleteController' => 'applications/phame/controller/blog/PhameBlogDeleteController.php',
|
||||||
'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php',
|
'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php',
|
||||||
|
'PhameBlogEditor' => 'applications/phame/editor/PhameBlogEditor.php',
|
||||||
'PhameBlogFeedController' => 'applications/phame/controller/blog/PhameBlogFeedController.php',
|
'PhameBlogFeedController' => 'applications/phame/controller/blog/PhameBlogFeedController.php',
|
||||||
'PhameBlogListController' => 'applications/phame/controller/blog/PhameBlogListController.php',
|
'PhameBlogListController' => 'applications/phame/controller/blog/PhameBlogListController.php',
|
||||||
'PhameBlogLiveController' => 'applications/phame/controller/blog/PhameBlogLiveController.php',
|
'PhameBlogLiveController' => 'applications/phame/controller/blog/PhameBlogLiveController.php',
|
||||||
'PhameBlogQuery' => 'applications/phame/query/PhameBlogQuery.php',
|
'PhameBlogQuery' => 'applications/phame/query/PhameBlogQuery.php',
|
||||||
'PhameBlogSkin' => 'applications/phame/skins/PhameBlogSkin.php',
|
'PhameBlogSkin' => 'applications/phame/skins/PhameBlogSkin.php',
|
||||||
|
'PhameBlogTransaction' => 'applications/phame/storage/PhameBlogTransaction.php',
|
||||||
'PhameBlogViewController' => 'applications/phame/controller/blog/PhameBlogViewController.php',
|
'PhameBlogViewController' => 'applications/phame/controller/blog/PhameBlogViewController.php',
|
||||||
'PhameCelerityResources' => 'applications/phame/celerity/PhameCelerityResources.php',
|
'PhameCelerityResources' => 'applications/phame/celerity/PhameCelerityResources.php',
|
||||||
'PhameConduitAPIMethod' => 'applications/phame/conduit/PhameConduitAPIMethod.php',
|
'PhameConduitAPIMethod' => 'applications/phame/conduit/PhameConduitAPIMethod.php',
|
||||||
|
@ -6250,11 +6252,13 @@ phutil_register_library_map(array(
|
||||||
),
|
),
|
||||||
'PhameBlogDeleteController' => 'PhameController',
|
'PhameBlogDeleteController' => 'PhameController',
|
||||||
'PhameBlogEditController' => 'PhameController',
|
'PhameBlogEditController' => 'PhameController',
|
||||||
|
'PhameBlogEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
'PhameBlogFeedController' => 'PhameController',
|
'PhameBlogFeedController' => 'PhameController',
|
||||||
'PhameBlogListController' => 'PhameController',
|
'PhameBlogListController' => 'PhameController',
|
||||||
'PhameBlogLiveController' => 'PhameController',
|
'PhameBlogLiveController' => 'PhameController',
|
||||||
'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhameBlogSkin' => 'PhabricatorController',
|
'PhameBlogSkin' => 'PhabricatorController',
|
||||||
|
'PhameBlogTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
'PhameBlogViewController' => 'PhameController',
|
'PhameBlogViewController' => 'PhameController',
|
||||||
'PhameCelerityResources' => 'CelerityResources',
|
'PhameCelerityResources' => 'CelerityResources',
|
||||||
'PhameConduitAPIMethod' => 'ConduitAPIMethod',
|
'PhameConduitAPIMethod' => 'ConduitAPIMethod',
|
||||||
|
|
|
@ -2,19 +2,13 @@
|
||||||
|
|
||||||
final class PhameBlogDeleteController extends PhameController {
|
final class PhameBlogDeleteController 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();
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
|
||||||
$blog = id(new PhameBlogQuery())
|
$blog = id(new PhameBlogQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($id))
|
||||||
->requireCapabilities(
|
->requireCapabilities(
|
||||||
array(
|
array(
|
||||||
PhabricatorPolicyCapability::CAN_EDIT,
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
|
|
@ -3,20 +3,14 @@
|
||||||
final class PhameBlogEditController
|
final class PhameBlogEditController
|
||||||
extends PhameController {
|
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();
|
||||||
|
|
||||||
if ($this->id) {
|
$id = $request->getURIData('id');
|
||||||
|
if ($id) {
|
||||||
$blog = id(new PhameBlogQuery())
|
$blog = id(new PhameBlogQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($id))
|
||||||
->requireCapabilities(
|
->requireCapabilities(
|
||||||
array(
|
array(
|
||||||
PhabricatorPolicyCapability::CAN_EDIT,
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
@ -30,76 +24,75 @@ final class PhameBlogEditController
|
||||||
$page_title = pht('Edit Blog');
|
$page_title = pht('Edit Blog');
|
||||||
$cancel_uri = $this->getApplicationURI('blog/view/'.$blog->getID().'/');
|
$cancel_uri = $this->getApplicationURI('blog/view/'.$blog->getID().'/');
|
||||||
} else {
|
} else {
|
||||||
$blog = id(new PhameBlog())
|
$blog = PhameBlog::initializeNewBlog($user);
|
||||||
->setCreatorPHID($user->getPHID());
|
|
||||||
|
|
||||||
$blog->setViewPolicy(PhabricatorPolicies::POLICY_USER);
|
|
||||||
$blog->setEditPolicy(PhabricatorPolicies::POLICY_USER);
|
|
||||||
$blog->setJoinPolicy(PhabricatorPolicies::POLICY_USER);
|
|
||||||
|
|
||||||
$submit_button = pht('Create Blog');
|
$submit_button = pht('Create Blog');
|
||||||
$page_title = pht('Create Blog');
|
$page_title = pht('Create Blog');
|
||||||
$cancel_uri = $this->getApplicationURI();
|
$cancel_uri = $this->getApplicationURI();
|
||||||
}
|
}
|
||||||
|
$name = $blog->getName();
|
||||||
|
$description = $blog->getDescription();
|
||||||
|
$custom_domain = $blog->getDomain();
|
||||||
|
$skin = $blog->getSkin();
|
||||||
|
$can_view = $blog->getViewPolicy();
|
||||||
|
$can_edit = $blog->getEditPolicy();
|
||||||
|
$can_join = $blog->getJoinPolicy();
|
||||||
|
|
||||||
$e_name = true;
|
$e_name = true;
|
||||||
$e_custom_domain = null;
|
$e_custom_domain = null;
|
||||||
$errors = array();
|
$e_view_policy = null;
|
||||||
|
$validation_exception = null;
|
||||||
if ($request->isFormPost()) {
|
if ($request->isFormPost()) {
|
||||||
$name = $request->getStr('name');
|
$name = $request->getStr('name');
|
||||||
$description = $request->getStr('description');
|
$description = $request->getStr('description');
|
||||||
$custom_domain = $request->getStr('custom_domain');
|
$custom_domain = nonempty($request->getStr('custom_domain'), null);
|
||||||
$skin = $request->getStr('skin');
|
$skin = $request->getStr('skin');
|
||||||
|
$can_view = $request->getStr('can_view');
|
||||||
|
$can_edit = $request->getStr('can_edit');
|
||||||
|
$can_join = $request->getStr('can_join');
|
||||||
|
|
||||||
if (empty($name)) {
|
$xactions = array(
|
||||||
$errors[] = pht('You must give the blog a name.');
|
id(new PhameBlogTransaction())
|
||||||
$e_name = pht('Required');
|
->setTransactionType(PhameBlogTransaction::TYPE_NAME)
|
||||||
} else {
|
->setNewValue($name),
|
||||||
$e_name = null;
|
id(new PhameBlogTransaction())
|
||||||
}
|
->setTransactionType(PhameBlogTransaction::TYPE_DESCRIPTION)
|
||||||
|
->setNewValue($description),
|
||||||
|
id(new PhameBlogTransaction())
|
||||||
|
->setTransactionType(PhameBlogTransaction::TYPE_DOMAIN)
|
||||||
|
->setNewValue($custom_domain),
|
||||||
|
id(new PhameBlogTransaction())
|
||||||
|
->setTransactionType(PhameBlogTransaction::TYPE_SKIN)
|
||||||
|
->setNewValue($skin),
|
||||||
|
id(new PhameBlogTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
|
||||||
|
->setNewValue($can_view),
|
||||||
|
id(new PhameBlogTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
|
||||||
|
->setNewValue($can_edit),
|
||||||
|
id(new PhameBlogTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY)
|
||||||
|
->setNewValue($can_join),
|
||||||
|
);
|
||||||
|
|
||||||
$blog->setName($name);
|
$editor = id(new PhameBlogEditor())
|
||||||
$blog->setDescription($description);
|
->setActor($user)
|
||||||
$blog->setDomain(nonempty($custom_domain, null));
|
->setContentSourceFromRequest($request)
|
||||||
$blog->setSkin($skin);
|
->setContinueOnNoEffect(true);
|
||||||
$blog->setViewPolicy($request->getStr('can_view'));
|
|
||||||
$blog->setEditPolicy($request->getStr('can_edit'));
|
|
||||||
$blog->setJoinPolicy($request->getStr('can_join'));
|
|
||||||
|
|
||||||
if (!empty($custom_domain)) {
|
try {
|
||||||
list($error_label, $error_text) =
|
$editor->applyTransactions($blog, $xactions);
|
||||||
$blog->validateCustomDomain($custom_domain);
|
return id(new AphrontRedirectResponse())
|
||||||
if ($error_label) {
|
->setURI($this->getApplicationURI('blog/view/'.$blog->getID().'/'));
|
||||||
$errors[] = $error_text;
|
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||||
$e_custom_domain = $error_label;
|
$validation_exception = $ex;
|
||||||
}
|
|
||||||
if ($blog->getViewPolicy() != PhabricatorPolicies::POLICY_PUBLIC) {
|
|
||||||
$errors[] = pht(
|
|
||||||
'For custom domains to work, the blog must have a view policy of '.
|
|
||||||
'public.');
|
|
||||||
// Prefer earlier labels for the multiple error scenario.
|
|
||||||
if (!$e_custom_domain) {
|
|
||||||
$e_custom_domain = pht('Invalid Policy');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't let users remove their ability to edit blogs.
|
$e_name = $validation_exception->getShortMessage(
|
||||||
PhabricatorPolicyFilter::mustRetainCapability(
|
PhameBlogTransaction::TYPE_NAME);
|
||||||
$user,
|
$e_custom_domain = $validation_exception->getShortMessage(
|
||||||
$blog,
|
PhameBlogTransaction::TYPE_DOMAIN);
|
||||||
PhabricatorPolicyCapability::CAN_EDIT);
|
$e_view_policy = $validation_exception->getShortMessage(
|
||||||
|
PhabricatorTransactions::TYPE_VIEW_POLICY);
|
||||||
if (!$errors) {
|
|
||||||
try {
|
|
||||||
$blog->save();
|
|
||||||
return id(new AphrontRedirectResponse())
|
|
||||||
->setURI($this->getApplicationURI('blog/view/'.$blog->getID().'/'));
|
|
||||||
} catch (AphrontDuplicateKeyQueryException $ex) {
|
|
||||||
$errors[] = pht('Domain must be unique.');
|
|
||||||
$e_custom_domain = pht('Not Unique');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +110,7 @@ final class PhameBlogEditController
|
||||||
id(new AphrontFormTextControl())
|
id(new AphrontFormTextControl())
|
||||||
->setLabel(pht('Name'))
|
->setLabel(pht('Name'))
|
||||||
->setName('name')
|
->setName('name')
|
||||||
->setValue($blog->getName())
|
->setValue($name)
|
||||||
->setID('blog-name')
|
->setID('blog-name')
|
||||||
->setError($e_name))
|
->setError($e_name))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
|
@ -125,7 +118,7 @@ final class PhameBlogEditController
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
->setLabel(pht('Description'))
|
->setLabel(pht('Description'))
|
||||||
->setName('description')
|
->setName('description')
|
||||||
->setValue($blog->getDescription())
|
->setValue($description)
|
||||||
->setID('blog-description')
|
->setID('blog-description')
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
->setDisableMacros(true))
|
->setDisableMacros(true))
|
||||||
|
@ -135,6 +128,8 @@ final class PhameBlogEditController
|
||||||
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
||||||
->setPolicyObject($blog)
|
->setPolicyObject($blog)
|
||||||
->setPolicies($policies)
|
->setPolicies($policies)
|
||||||
|
->setError($e_view_policy)
|
||||||
|
->setValue($can_view)
|
||||||
->setName('can_view'))
|
->setName('can_view'))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormPolicyControl())
|
id(new AphrontFormPolicyControl())
|
||||||
|
@ -142,6 +137,7 @@ final class PhameBlogEditController
|
||||||
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
||||||
->setPolicyObject($blog)
|
->setPolicyObject($blog)
|
||||||
->setPolicies($policies)
|
->setPolicies($policies)
|
||||||
|
->setValue($can_edit)
|
||||||
->setName('can_edit'))
|
->setName('can_edit'))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormPolicyControl())
|
id(new AphrontFormPolicyControl())
|
||||||
|
@ -149,12 +145,13 @@ final class PhameBlogEditController
|
||||||
->setCapability(PhabricatorPolicyCapability::CAN_JOIN)
|
->setCapability(PhabricatorPolicyCapability::CAN_JOIN)
|
||||||
->setPolicyObject($blog)
|
->setPolicyObject($blog)
|
||||||
->setPolicies($policies)
|
->setPolicies($policies)
|
||||||
|
->setValue($can_join)
|
||||||
->setName('can_join'))
|
->setName('can_join'))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormTextControl())
|
id(new AphrontFormTextControl())
|
||||||
->setLabel(pht('Custom Domain'))
|
->setLabel(pht('Custom Domain'))
|
||||||
->setName('custom_domain')
|
->setName('custom_domain')
|
||||||
->setValue($blog->getDomain())
|
->setValue($custom_domain)
|
||||||
->setCaption(
|
->setCaption(
|
||||||
pht('Must include at least one dot (.), e.g. blog.example.com'))
|
pht('Must include at least one dot (.), e.g. blog.example.com'))
|
||||||
->setError($e_custom_domain))
|
->setError($e_custom_domain))
|
||||||
|
@ -162,7 +159,7 @@ final class PhameBlogEditController
|
||||||
id(new AphrontFormSelectControl())
|
id(new AphrontFormSelectControl())
|
||||||
->setLabel(pht('Skin'))
|
->setLabel(pht('Skin'))
|
||||||
->setName('skin')
|
->setName('skin')
|
||||||
->setValue($blog->getSkin())
|
->setValue($skin)
|
||||||
->setOptions($skins))
|
->setOptions($skins))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
|
@ -171,14 +168,14 @@ final class PhameBlogEditController
|
||||||
|
|
||||||
$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($page_title, $this->getApplicationURI('blog/new'));
|
$crumbs->addTextCrumb($page_title, $this->getApplicationURI('blog/new'));
|
||||||
|
|
||||||
$nav = $this->renderSideNavFilterView();
|
$nav = $this->renderSideNavFilterView();
|
||||||
$nav->selectFilter($this->id ? null : 'blog/new');
|
$nav->selectFilter($id ? null : 'blog/new');
|
||||||
$nav->appendChild(
|
$nav->appendChild(
|
||||||
array(
|
array(
|
||||||
$crumbs,
|
$crumbs,
|
||||||
|
|
|
@ -2,23 +2,17 @@
|
||||||
|
|
||||||
final class PhameBlogFeedController extends PhameController {
|
final class PhameBlogFeedController extends PhameController {
|
||||||
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
public function shouldRequireLogin() {
|
public function shouldRequireLogin() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$this->id = $data['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
|
||||||
$blog = id(new PhameBlogQuery())
|
$blog = id(new PhameBlogQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($id))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
if (!$blog) {
|
if (!$blog) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
|
|
||||||
final class PhameBlogListController extends PhameController {
|
final class PhameBlogListController extends PhameController {
|
||||||
|
|
||||||
private $filter;
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->filter = idx($data, 'filter');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
|
|
||||||
$nav = $this->renderSideNavFilterView(null);
|
$nav = $this->renderSideNavFilterView(null);
|
||||||
$filter = $nav->selectFilter('blog/'.$this->filter, 'blog/user');
|
$filter = $request->getURIData('filter');
|
||||||
|
$filter = $nav->selectFilter('blog/'.$filter, 'blog/user');
|
||||||
|
|
||||||
$query = id(new PhameBlogQuery())
|
$query = id(new PhameBlogQuery())
|
||||||
->setViewer($user);
|
->setViewer($user);
|
||||||
|
|
|
@ -2,25 +2,17 @@
|
||||||
|
|
||||||
final class PhameBlogLiveController extends PhameController {
|
final class PhameBlogLiveController extends PhameController {
|
||||||
|
|
||||||
private $id;
|
|
||||||
private $more;
|
|
||||||
|
|
||||||
public function shouldAllowPublic() {
|
public function shouldAllowPublic() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$this->id = idx($data, 'id');
|
|
||||||
$this->more = idx($data, 'more', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
|
||||||
$blog = id(new PhameBlogQuery())
|
$blog = id(new PhameBlogQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($id))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
if (!$blog) {
|
if (!$blog) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
|
@ -55,7 +47,8 @@ final class PhameBlogLiveController extends PhameController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$phame_request = clone $request;
|
$phame_request = clone $request;
|
||||||
$phame_request->setPath('/'.ltrim($this->more, '/'));
|
$more = $phame_request->getURIData('more', '');
|
||||||
|
$phame_request->setPath('/'.ltrim($more, '/'));
|
||||||
|
|
||||||
$uri = $blog->getLiveURI();
|
$uri = $blog->getLiveURI();
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,13 @@
|
||||||
|
|
||||||
final class PhameBlogViewController extends PhameController {
|
final class PhameBlogViewController 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();
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
|
||||||
$blog = id(new PhameBlogQuery())
|
$blog = id(new PhameBlogQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($id))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
if (!$blog) {
|
if (!$blog) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
|
|
189
src/applications/phame/editor/PhameBlogEditor.php
Normal file
189
src/applications/phame/editor/PhameBlogEditor.php
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhameBlogEditor
|
||||||
|
extends PhabricatorApplicationTransactionEditor {
|
||||||
|
|
||||||
|
public function getEditorApplicationClass() {
|
||||||
|
return 'PhabricatorPhameApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEditorObjectsDescription() {
|
||||||
|
return pht('Blogs');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTransactionTypes() {
|
||||||
|
$types = parent::getTransactionTypes();
|
||||||
|
|
||||||
|
$types[] = PhameBlogTransaction::TYPE_NAME;
|
||||||
|
$types[] = PhameBlogTransaction::TYPE_DESCRIPTION;
|
||||||
|
$types[] = PhameBlogTransaction::TYPE_DOMAIN;
|
||||||
|
$types[] = PhameBlogTransaction::TYPE_SKIN;
|
||||||
|
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||||
|
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||||
|
$types[] = PhabricatorTransactions::TYPE_JOIN_POLICY;
|
||||||
|
|
||||||
|
return $types;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCustomTransactionOldValue(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case PhameBlogTransaction::TYPE_NAME:
|
||||||
|
return $object->getName();
|
||||||
|
case PhameBlogTransaction::TYPE_DESCRIPTION:
|
||||||
|
return $object->getDescription();
|
||||||
|
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||||
|
return $object->getDomain();
|
||||||
|
case PhameBlogTransaction::TYPE_SKIN:
|
||||||
|
return $object->getSkin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCustomTransactionNewValue(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case PhameBlogTransaction::TYPE_NAME:
|
||||||
|
case PhameBlogTransaction::TYPE_DESCRIPTION:
|
||||||
|
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||||
|
case PhameBlogTransaction::TYPE_SKIN:
|
||||||
|
return $xaction->getNewValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function applyCustomInternalTransaction(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case PhameBlogTransaction::TYPE_NAME:
|
||||||
|
return $object->setName($xaction->getNewValue());
|
||||||
|
case PhameBlogTransaction::TYPE_DESCRIPTION:
|
||||||
|
return $object->setDescription($xaction->getNewValue());
|
||||||
|
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||||
|
return $object->setDomain($xaction->getNewValue());
|
||||||
|
case PhameBlogTransaction::TYPE_SKIN:
|
||||||
|
return $object->setSkin($xaction->getNewValue());
|
||||||
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
||||||
|
$object->setViewPolicy($xaction->getNewValue());
|
||||||
|
return;
|
||||||
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
||||||
|
$object->setEditPolicy($xaction->getNewValue());
|
||||||
|
return;
|
||||||
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
||||||
|
$object->setJoinPolicy($xaction->getNewValue());
|
||||||
|
return;
|
||||||
|
case PhabricatorTransactions::TYPE_COMMENT:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function applyCustomExternalTransaction(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case PhameBlogTransaction::TYPE_NAME:
|
||||||
|
case PhameBlogTransaction::TYPE_DESCRIPTION:
|
||||||
|
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||||
|
case PhameBlogTransaction::TYPE_SKIN:
|
||||||
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
||||||
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
||||||
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
||||||
|
case PhabricatorTransactions::TYPE_COMMENT:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function validateTransaction(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
$type,
|
||||||
|
array $xactions) {
|
||||||
|
|
||||||
|
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case PhameBlogTransaction::TYPE_NAME:
|
||||||
|
$missing = $this->validateIsEmptyTextField(
|
||||||
|
$object->getName(),
|
||||||
|
$xactions);
|
||||||
|
|
||||||
|
if ($missing) {
|
||||||
|
$error = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
pht('Required'),
|
||||||
|
pht('Name is required.'),
|
||||||
|
nonempty(last($xactions), null));
|
||||||
|
|
||||||
|
$error->setIsMissingFieldError(true);
|
||||||
|
$errors[] = $error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||||
|
$custom_domain = last($xactions)->getNewValue();
|
||||||
|
if (empty($custom_domain)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
list($error_label, $error_text) =
|
||||||
|
$object->validateCustomDomain($custom_domain);
|
||||||
|
if ($error_label) {
|
||||||
|
$error = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
$error_label,
|
||||||
|
$error_text,
|
||||||
|
nonempty(last($xactions), null));
|
||||||
|
$errors[] = $error;
|
||||||
|
}
|
||||||
|
if ($object->getViewPolicy() != PhabricatorPolicies::POLICY_PUBLIC) {
|
||||||
|
$error_text = pht(
|
||||||
|
'For custom domains to work, the blog must have a view policy of '.
|
||||||
|
'public.');
|
||||||
|
$error = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
PhabricatorTransactions::TYPE_VIEW_POLICY,
|
||||||
|
pht('Invalid Policy'),
|
||||||
|
$error_text,
|
||||||
|
nonempty(last($xactions), null));
|
||||||
|
$errors[] = $error;
|
||||||
|
}
|
||||||
|
$duplicate_blog = id(new PhameBlogQuery())
|
||||||
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
->withDomain($custom_domain)
|
||||||
|
->executeOne();
|
||||||
|
if ($duplicate_blog && $duplicate_blog->getID() != $object->getID()) {
|
||||||
|
$error = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
pht('Not Unique'),
|
||||||
|
pht('Domain must be unique; another blog already has this domain.'),
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,9 +16,6 @@ final class PhameBlog extends PhameDAO
|
||||||
protected $editPolicy;
|
protected $editPolicy;
|
||||||
protected $joinPolicy;
|
protected $joinPolicy;
|
||||||
|
|
||||||
private $bloggerPHIDs = self::ATTACHABLE;
|
|
||||||
private $bloggers = self::ATTACHABLE;
|
|
||||||
|
|
||||||
static private $requestBlog;
|
static private $requestBlog;
|
||||||
|
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
|
@ -57,6 +54,15 @@ final class PhameBlog extends PhameDAO
|
||||||
PhabricatorPhameBlogPHIDType::TYPECONST);
|
PhabricatorPhameBlogPHIDType::TYPECONST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function initializeNewBlog(PhabricatorUser $actor) {
|
||||||
|
$blog = id(new PhameBlog())
|
||||||
|
->setCreatorPHID($actor->getPHID())
|
||||||
|
->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())
|
||||||
|
->setEditPolicy(PhabricatorPolicies::POLICY_USER)
|
||||||
|
->setJoinPolicy(PhabricatorPolicies::POLICY_USER);
|
||||||
|
return $blog;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSkinRenderer(AphrontRequest $request) {
|
public function getSkinRenderer(AphrontRequest $request) {
|
||||||
$spec = PhameSkinSpecification::loadOneSkinSpecification(
|
$spec = PhameSkinSpecification::loadOneSkinSpecification(
|
||||||
$this->getSkin());
|
$this->getSkin());
|
||||||
|
@ -157,22 +163,6 @@ final class PhameBlog extends PhameDAO
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBloggerPHIDs() {
|
|
||||||
return $this->assertAttached($this->bloggerPHIDs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attachBloggers(array $bloggers) {
|
|
||||||
assert_instances_of($bloggers, 'PhabricatorObjectHandle');
|
|
||||||
|
|
||||||
$this->bloggers = $bloggers;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBloggers() {
|
|
||||||
return $this->assertAttached($this->bloggers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSkin() {
|
public function getSkin() {
|
||||||
$config = coalesce($this->getConfigData(), array());
|
$config = coalesce($this->getConfigData(), array());
|
||||||
return idx($config, 'skin', self::SKIN_DEFAULT);
|
return idx($config, 'skin', self::SKIN_DEFAULT);
|
||||||
|
|
174
src/applications/phame/storage/PhameBlogTransaction.php
Normal file
174
src/applications/phame/storage/PhameBlogTransaction.php
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhameBlogTransaction
|
||||||
|
extends PhabricatorApplicationTransaction {
|
||||||
|
|
||||||
|
const TYPE_NAME = 'phame.blog.name';
|
||||||
|
const TYPE_DESCRIPTION = 'phame.blog.description';
|
||||||
|
const TYPE_DOMAIN = 'phame.blog.domain';
|
||||||
|
const TYPE_SKIN = 'phame.blog.skin';
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'phame';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionType() {
|
||||||
|
return PhabricatorPhameBlogPHIDType::TYPECONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shouldHide() {
|
||||||
|
$old = $this->getOldValue();
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_DESCRIPTION:
|
||||||
|
return ($old === null);
|
||||||
|
}
|
||||||
|
return parent::shouldHide();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIcon() {
|
||||||
|
$old = $this->getOldValue();
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_NAME:
|
||||||
|
if ($old === null) {
|
||||||
|
return 'fa-plus';
|
||||||
|
} else {
|
||||||
|
return 'fa-pencil';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case self::TYPE_DESCRIPTION:
|
||||||
|
case self::TYPE_DOMAIN:
|
||||||
|
case self::TYPE_SKIN:
|
||||||
|
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_NAME:
|
||||||
|
if ($old === null) {
|
||||||
|
return pht(
|
||||||
|
'%s created this blog.',
|
||||||
|
$this->renderHandleLink($author_phid));
|
||||||
|
} else {
|
||||||
|
return pht(
|
||||||
|
'%s updated the blog\'s name to "%s".',
|
||||||
|
$this->renderHandleLink($author_phid),
|
||||||
|
$new);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case self::TYPE_DESCRIPTION:
|
||||||
|
return pht(
|
||||||
|
'%s updated the blog\'s description.',
|
||||||
|
$this->renderHandleLink($author_phid));
|
||||||
|
break;
|
||||||
|
case self::TYPE_DOMAIN:
|
||||||
|
return pht(
|
||||||
|
'%s updated the blog\'s domain to "%s".',
|
||||||
|
$this->renderHandleLink($author_phid),
|
||||||
|
$new);
|
||||||
|
break;
|
||||||
|
case self::TYPE_SKIN:
|
||||||
|
return pht(
|
||||||
|
'%s updated the blog\'s skin 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_NAME:
|
||||||
|
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_DESCRIPTION:
|
||||||
|
return pht(
|
||||||
|
'%s updated the description for %s.',
|
||||||
|
$this->renderHandleLink($author_phid),
|
||||||
|
$this->renderHandleLink($object_phid));
|
||||||
|
break;
|
||||||
|
case self::TYPE_DOMAIN:
|
||||||
|
return pht(
|
||||||
|
'%s updated the domain for %s.',
|
||||||
|
$this->renderHandleLink($author_phid),
|
||||||
|
$this->renderHandleLink($object_phid));
|
||||||
|
break;
|
||||||
|
case self::TYPE_SKIN:
|
||||||
|
return pht(
|
||||||
|
'%s updated the skin 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_NAME:
|
||||||
|
if ($old === null) {
|
||||||
|
return PhabricatorTransactions::COLOR_GREEN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function hasChangeDetails() {
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_DESCRIPTION:
|
||||||
|
return ($this->getOldValue() !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::hasChangeDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderChangeDetails(PhabricatorUser $viewer) {
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_DESCRIPTION:
|
||||||
|
$old = $this->getOldValue();
|
||||||
|
$new = $this->getNewValue();
|
||||||
|
|
||||||
|
return $this->renderTextCorpusChangeDetails(
|
||||||
|
$viewer,
|
||||||
|
$old,
|
||||||
|
$new);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::renderChangeDetails($viewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue