1
0
Fork 0
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:
Bob Trahan 2015-05-14 17:05:58 -07:00
parent 705c1e6498
commit f16dda288d
11 changed files with 481 additions and 139 deletions

View 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};

View file

@ -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',

View file

@ -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,

View file

@ -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,

View file

@ -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();

View file

@ -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);

View file

@ -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();

View file

@ -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();

View 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;
}
}

View file

@ -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);

View 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);
}
}