@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+481 -139
+19
resources/sql/autopatches/20150514.phame.blog.xaction.sql
··· 1 + CREATE TABLE {$NAMESPACE}_phame.phame_blogtransaction ( 2 + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 + phid VARBINARY(64) NOT NULL, 4 + authorPHID VARBINARY(64) NOT NULL, 5 + objectPHID VARBINARY(64) NOT NULL, 6 + viewPolicy VARBINARY(64) NOT NULL, 7 + editPolicy VARBINARY(64) NOT NULL, 8 + commentPHID VARBINARY(64) DEFAULT NULL, 9 + commentVersion INT UNSIGNED NOT NULL, 10 + transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL, 11 + oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 12 + newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 13 + contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 14 + metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 15 + dateCreated INT UNSIGNED NOT NULL, 16 + dateModified INT UNSIGNED NOT NULL, 17 + UNIQUE KEY `key_phid` (`phid`), 18 + KEY `key_object` (`objectPHID`) 19 + ) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
+4
src/__phutil_library_map__.php
··· 2775 2775 'PhameBlog' => 'applications/phame/storage/PhameBlog.php', 2776 2776 'PhameBlogDeleteController' => 'applications/phame/controller/blog/PhameBlogDeleteController.php', 2777 2777 'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php', 2778 + 'PhameBlogEditor' => 'applications/phame/editor/PhameBlogEditor.php', 2778 2779 'PhameBlogFeedController' => 'applications/phame/controller/blog/PhameBlogFeedController.php', 2779 2780 'PhameBlogListController' => 'applications/phame/controller/blog/PhameBlogListController.php', 2780 2781 'PhameBlogLiveController' => 'applications/phame/controller/blog/PhameBlogLiveController.php', 2781 2782 'PhameBlogQuery' => 'applications/phame/query/PhameBlogQuery.php', 2782 2783 'PhameBlogSkin' => 'applications/phame/skins/PhameBlogSkin.php', 2784 + 'PhameBlogTransaction' => 'applications/phame/storage/PhameBlogTransaction.php', 2783 2785 'PhameBlogViewController' => 'applications/phame/controller/blog/PhameBlogViewController.php', 2784 2786 'PhameCelerityResources' => 'applications/phame/celerity/PhameCelerityResources.php', 2785 2787 'PhameConduitAPIMethod' => 'applications/phame/conduit/PhameConduitAPIMethod.php', ··· 6250 6252 ), 6251 6253 'PhameBlogDeleteController' => 'PhameController', 6252 6254 'PhameBlogEditController' => 'PhameController', 6255 + 'PhameBlogEditor' => 'PhabricatorApplicationTransactionEditor', 6253 6256 'PhameBlogFeedController' => 'PhameController', 6254 6257 'PhameBlogListController' => 'PhameController', 6255 6258 'PhameBlogLiveController' => 'PhameController', 6256 6259 'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 6257 6260 'PhameBlogSkin' => 'PhabricatorController', 6261 + 'PhameBlogTransaction' => 'PhabricatorApplicationTransaction', 6258 6262 'PhameBlogViewController' => 'PhameController', 6259 6263 'PhameCelerityResources' => 'CelerityResources', 6260 6264 'PhameConduitAPIMethod' => 'ConduitAPIMethod',
+3 -9
src/applications/phame/controller/blog/PhameBlogDeleteController.php
··· 2 2 3 3 final class PhameBlogDeleteController extends PhameController { 4 4 5 - private $id; 6 - 7 - public function willProcessRequest(array $data) { 8 - $this->id = $data['id']; 9 - } 10 - 11 - public function processRequest() { 12 - $request = $this->getRequest(); 5 + public function handleRequest(AphrontRequest $request) { 13 6 $user = $request->getUser(); 7 + $id = $request->getURIData('id'); 14 8 15 9 $blog = id(new PhameBlogQuery()) 16 10 ->setViewer($user) 17 - ->withIDs(array($this->id)) 11 + ->withIDs(array($id)) 18 12 ->requireCapabilities( 19 13 array( 20 14 PhabricatorPolicyCapability::CAN_EDIT,
+69 -72
src/applications/phame/controller/blog/PhameBlogEditController.php
··· 3 3 final class PhameBlogEditController 4 4 extends PhameController { 5 5 6 - private $id; 7 - 8 - public function willProcessRequest(array $data) { 9 - $this->id = idx($data, 'id'); 10 - } 11 - 12 - public function processRequest() { 13 - $request = $this->getRequest(); 6 + public function handleRequest(AphrontRequest $request) { 14 7 $user = $request->getUser(); 15 8 16 - if ($this->id) { 9 + $id = $request->getURIData('id'); 10 + if ($id) { 17 11 $blog = id(new PhameBlogQuery()) 18 12 ->setViewer($user) 19 - ->withIDs(array($this->id)) 13 + ->withIDs(array($id)) 20 14 ->requireCapabilities( 21 15 array( 22 16 PhabricatorPolicyCapability::CAN_EDIT, ··· 30 24 $page_title = pht('Edit Blog'); 31 25 $cancel_uri = $this->getApplicationURI('blog/view/'.$blog->getID().'/'); 32 26 } else { 33 - $blog = id(new PhameBlog()) 34 - ->setCreatorPHID($user->getPHID()); 35 - 36 - $blog->setViewPolicy(PhabricatorPolicies::POLICY_USER); 37 - $blog->setEditPolicy(PhabricatorPolicies::POLICY_USER); 38 - $blog->setJoinPolicy(PhabricatorPolicies::POLICY_USER); 27 + $blog = PhameBlog::initializeNewBlog($user); 39 28 40 29 $submit_button = pht('Create Blog'); 41 30 $page_title = pht('Create Blog'); 42 31 $cancel_uri = $this->getApplicationURI(); 43 32 } 44 - 45 - $e_name = true; 46 - $e_custom_domain = null; 47 - $errors = array(); 33 + $name = $blog->getName(); 34 + $description = $blog->getDescription(); 35 + $custom_domain = $blog->getDomain(); 36 + $skin = $blog->getSkin(); 37 + $can_view = $blog->getViewPolicy(); 38 + $can_edit = $blog->getEditPolicy(); 39 + $can_join = $blog->getJoinPolicy(); 48 40 41 + $e_name = true; 42 + $e_custom_domain = null; 43 + $e_view_policy = null; 44 + $validation_exception = null; 49 45 if ($request->isFormPost()) { 50 46 $name = $request->getStr('name'); 51 47 $description = $request->getStr('description'); 52 - $custom_domain = $request->getStr('custom_domain'); 48 + $custom_domain = nonempty($request->getStr('custom_domain'), null); 53 49 $skin = $request->getStr('skin'); 50 + $can_view = $request->getStr('can_view'); 51 + $can_edit = $request->getStr('can_edit'); 52 + $can_join = $request->getStr('can_join'); 54 53 55 - if (empty($name)) { 56 - $errors[] = pht('You must give the blog a name.'); 57 - $e_name = pht('Required'); 58 - } else { 59 - $e_name = null; 60 - } 54 + $xactions = array( 55 + id(new PhameBlogTransaction()) 56 + ->setTransactionType(PhameBlogTransaction::TYPE_NAME) 57 + ->setNewValue($name), 58 + id(new PhameBlogTransaction()) 59 + ->setTransactionType(PhameBlogTransaction::TYPE_DESCRIPTION) 60 + ->setNewValue($description), 61 + id(new PhameBlogTransaction()) 62 + ->setTransactionType(PhameBlogTransaction::TYPE_DOMAIN) 63 + ->setNewValue($custom_domain), 64 + id(new PhameBlogTransaction()) 65 + ->setTransactionType(PhameBlogTransaction::TYPE_SKIN) 66 + ->setNewValue($skin), 67 + id(new PhameBlogTransaction()) 68 + ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) 69 + ->setNewValue($can_view), 70 + id(new PhameBlogTransaction()) 71 + ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) 72 + ->setNewValue($can_edit), 73 + id(new PhameBlogTransaction()) 74 + ->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY) 75 + ->setNewValue($can_join), 76 + ); 61 77 62 - $blog->setName($name); 63 - $blog->setDescription($description); 64 - $blog->setDomain(nonempty($custom_domain, null)); 65 - $blog->setSkin($skin); 66 - $blog->setViewPolicy($request->getStr('can_view')); 67 - $blog->setEditPolicy($request->getStr('can_edit')); 68 - $blog->setJoinPolicy($request->getStr('can_join')); 78 + $editor = id(new PhameBlogEditor()) 79 + ->setActor($user) 80 + ->setContentSourceFromRequest($request) 81 + ->setContinueOnNoEffect(true); 69 82 70 - if (!empty($custom_domain)) { 71 - list($error_label, $error_text) = 72 - $blog->validateCustomDomain($custom_domain); 73 - if ($error_label) { 74 - $errors[] = $error_text; 75 - $e_custom_domain = $error_label; 76 - } 77 - if ($blog->getViewPolicy() != PhabricatorPolicies::POLICY_PUBLIC) { 78 - $errors[] = pht( 79 - 'For custom domains to work, the blog must have a view policy of '. 80 - 'public.'); 81 - // Prefer earlier labels for the multiple error scenario. 82 - if (!$e_custom_domain) { 83 - $e_custom_domain = pht('Invalid Policy'); 84 - } 85 - } 86 - } 87 - 88 - // Don't let users remove their ability to edit blogs. 89 - PhabricatorPolicyFilter::mustRetainCapability( 90 - $user, 91 - $blog, 92 - PhabricatorPolicyCapability::CAN_EDIT); 83 + try { 84 + $editor->applyTransactions($blog, $xactions); 85 + return id(new AphrontRedirectResponse()) 86 + ->setURI($this->getApplicationURI('blog/view/'.$blog->getID().'/')); 87 + } catch (PhabricatorApplicationTransactionValidationException $ex) { 88 + $validation_exception = $ex; 93 89 94 - if (!$errors) { 95 - try { 96 - $blog->save(); 97 - return id(new AphrontRedirectResponse()) 98 - ->setURI($this->getApplicationURI('blog/view/'.$blog->getID().'/')); 99 - } catch (AphrontDuplicateKeyQueryException $ex) { 100 - $errors[] = pht('Domain must be unique.'); 101 - $e_custom_domain = pht('Not Unique'); 102 - } 90 + $e_name = $validation_exception->getShortMessage( 91 + PhameBlogTransaction::TYPE_NAME); 92 + $e_custom_domain = $validation_exception->getShortMessage( 93 + PhameBlogTransaction::TYPE_DOMAIN); 94 + $e_view_policy = $validation_exception->getShortMessage( 95 + PhabricatorTransactions::TYPE_VIEW_POLICY); 103 96 } 104 97 } 105 98 ··· 117 110 id(new AphrontFormTextControl()) 118 111 ->setLabel(pht('Name')) 119 112 ->setName('name') 120 - ->setValue($blog->getName()) 113 + ->setValue($name) 121 114 ->setID('blog-name') 122 115 ->setError($e_name)) 123 116 ->appendChild( ··· 125 118 ->setUser($user) 126 119 ->setLabel(pht('Description')) 127 120 ->setName('description') 128 - ->setValue($blog->getDescription()) 121 + ->setValue($description) 129 122 ->setID('blog-description') 130 123 ->setUser($user) 131 124 ->setDisableMacros(true)) ··· 135 128 ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) 136 129 ->setPolicyObject($blog) 137 130 ->setPolicies($policies) 131 + ->setError($e_view_policy) 132 + ->setValue($can_view) 138 133 ->setName('can_view')) 139 134 ->appendChild( 140 135 id(new AphrontFormPolicyControl()) ··· 142 137 ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) 143 138 ->setPolicyObject($blog) 144 139 ->setPolicies($policies) 140 + ->setValue($can_edit) 145 141 ->setName('can_edit')) 146 142 ->appendChild( 147 143 id(new AphrontFormPolicyControl()) ··· 149 145 ->setCapability(PhabricatorPolicyCapability::CAN_JOIN) 150 146 ->setPolicyObject($blog) 151 147 ->setPolicies($policies) 148 + ->setValue($can_join) 152 149 ->setName('can_join')) 153 150 ->appendChild( 154 151 id(new AphrontFormTextControl()) 155 152 ->setLabel(pht('Custom Domain')) 156 153 ->setName('custom_domain') 157 - ->setValue($blog->getDomain()) 154 + ->setValue($custom_domain) 158 155 ->setCaption( 159 156 pht('Must include at least one dot (.), e.g. blog.example.com')) 160 157 ->setError($e_custom_domain)) ··· 162 159 id(new AphrontFormSelectControl()) 163 160 ->setLabel(pht('Skin')) 164 161 ->setName('skin') 165 - ->setValue($blog->getSkin()) 162 + ->setValue($skin) 166 163 ->setOptions($skins)) 167 164 ->appendChild( 168 165 id(new AphrontFormSubmitControl()) ··· 171 168 172 169 $form_box = id(new PHUIObjectBoxView()) 173 170 ->setHeaderText($page_title) 174 - ->setFormErrors($errors) 171 + ->setValidationException($validation_exception) 175 172 ->setForm($form); 176 173 177 174 $crumbs = $this->buildApplicationCrumbs(); 178 175 $crumbs->addTextCrumb($page_title, $this->getApplicationURI('blog/new')); 179 176 180 177 $nav = $this->renderSideNavFilterView(); 181 - $nav->selectFilter($this->id ? null : 'blog/new'); 178 + $nav->selectFilter($id ? null : 'blog/new'); 182 179 $nav->appendChild( 183 180 array( 184 181 $crumbs,
+3 -9
src/applications/phame/controller/blog/PhameBlogFeedController.php
··· 2 2 3 3 final class PhameBlogFeedController extends PhameController { 4 4 5 - private $id; 6 - 7 5 public function shouldRequireLogin() { 8 6 return false; 9 7 } 10 8 11 - public function willProcessRequest(array $data) { 12 - $this->id = $data['id']; 13 - } 14 - 15 - public function processRequest() { 16 - $request = $this->getRequest(); 9 + public function handleRequest(AphrontRequest $request) { 17 10 $user = $request->getUser(); 11 + $id = $request->getURIData('id'); 18 12 19 13 $blog = id(new PhameBlogQuery()) 20 14 ->setViewer($user) 21 - ->withIDs(array($this->id)) 15 + ->withIDs(array($id)) 22 16 ->executeOne(); 23 17 if (!$blog) { 24 18 return new Aphront404Response();
+3 -9
src/applications/phame/controller/blog/PhameBlogListController.php
··· 2 2 3 3 final class PhameBlogListController extends PhameController { 4 4 5 - private $filter; 6 - 7 - public function willProcessRequest(array $data) { 8 - $this->filter = idx($data, 'filter'); 9 - } 10 - 11 - public function processRequest() { 12 - $request = $this->getRequest(); 5 + public function handleRequest(AphrontRequest $request) { 13 6 $user = $request->getUser(); 14 7 15 8 $nav = $this->renderSideNavFilterView(null); 16 - $filter = $nav->selectFilter('blog/'.$this->filter, 'blog/user'); 9 + $filter = $request->getURIData('filter'); 10 + $filter = $nav->selectFilter('blog/'.$filter, 'blog/user'); 17 11 18 12 $query = id(new PhameBlogQuery()) 19 13 ->setViewer($user);
+5 -12
src/applications/phame/controller/blog/PhameBlogLiveController.php
··· 2 2 3 3 final class PhameBlogLiveController extends PhameController { 4 4 5 - private $id; 6 - private $more; 7 - 8 5 public function shouldAllowPublic() { 9 6 return true; 10 7 } 11 8 12 - public function willProcessRequest(array $data) { 13 - $this->id = idx($data, 'id'); 14 - $this->more = idx($data, 'more', ''); 15 - } 16 - 17 - public function processRequest() { 18 - $request = $this->getRequest(); 9 + public function handleRequest(AphrontRequest $request) { 19 10 $user = $request->getUser(); 11 + $id = $request->getURIData('id'); 20 12 21 13 $blog = id(new PhameBlogQuery()) 22 14 ->setViewer($user) 23 - ->withIDs(array($this->id)) 15 + ->withIDs(array($id)) 24 16 ->executeOne(); 25 17 if (!$blog) { 26 18 return new Aphront404Response(); ··· 55 47 } 56 48 57 49 $phame_request = clone $request; 58 - $phame_request->setPath('/'.ltrim($this->more, '/')); 50 + $more = $phame_request->getURIData('more', ''); 51 + $phame_request->setPath('/'.ltrim($more, '/')); 59 52 60 53 $uri = $blog->getLiveURI(); 61 54
+3 -9
src/applications/phame/controller/blog/PhameBlogViewController.php
··· 2 2 3 3 final class PhameBlogViewController extends PhameController { 4 4 5 - private $id; 6 - 7 - public function willProcessRequest(array $data) { 8 - $this->id = $data['id']; 9 - } 10 - 11 - public function processRequest() { 12 - $request = $this->getRequest(); 5 + public function handleRequest(AphrontRequest $request) { 13 6 $user = $request->getUser(); 7 + $id = $request->getURIData('id'); 14 8 15 9 $blog = id(new PhameBlogQuery()) 16 10 ->setViewer($user) 17 - ->withIDs(array($this->id)) 11 + ->withIDs(array($id)) 18 12 ->executeOne(); 19 13 if (!$blog) { 20 14 return new Aphront404Response();
+189
src/applications/phame/editor/PhameBlogEditor.php
··· 1 + <?php 2 + 3 + final class PhameBlogEditor 4 + extends PhabricatorApplicationTransactionEditor { 5 + 6 + public function getEditorApplicationClass() { 7 + return 'PhabricatorPhameApplication'; 8 + } 9 + 10 + public function getEditorObjectsDescription() { 11 + return pht('Blogs'); 12 + } 13 + 14 + public function getTransactionTypes() { 15 + $types = parent::getTransactionTypes(); 16 + 17 + $types[] = PhameBlogTransaction::TYPE_NAME; 18 + $types[] = PhameBlogTransaction::TYPE_DESCRIPTION; 19 + $types[] = PhameBlogTransaction::TYPE_DOMAIN; 20 + $types[] = PhameBlogTransaction::TYPE_SKIN; 21 + $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; 22 + $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; 23 + $types[] = PhabricatorTransactions::TYPE_JOIN_POLICY; 24 + 25 + return $types; 26 + } 27 + 28 + protected function getCustomTransactionOldValue( 29 + PhabricatorLiskDAO $object, 30 + PhabricatorApplicationTransaction $xaction) { 31 + 32 + switch ($xaction->getTransactionType()) { 33 + case PhameBlogTransaction::TYPE_NAME: 34 + return $object->getName(); 35 + case PhameBlogTransaction::TYPE_DESCRIPTION: 36 + return $object->getDescription(); 37 + case PhameBlogTransaction::TYPE_DOMAIN: 38 + return $object->getDomain(); 39 + case PhameBlogTransaction::TYPE_SKIN: 40 + return $object->getSkin(); 41 + } 42 + } 43 + 44 + protected function getCustomTransactionNewValue( 45 + PhabricatorLiskDAO $object, 46 + PhabricatorApplicationTransaction $xaction) { 47 + 48 + switch ($xaction->getTransactionType()) { 49 + case PhameBlogTransaction::TYPE_NAME: 50 + case PhameBlogTransaction::TYPE_DESCRIPTION: 51 + case PhameBlogTransaction::TYPE_DOMAIN: 52 + case PhameBlogTransaction::TYPE_SKIN: 53 + return $xaction->getNewValue(); 54 + } 55 + } 56 + 57 + protected function applyCustomInternalTransaction( 58 + PhabricatorLiskDAO $object, 59 + PhabricatorApplicationTransaction $xaction) { 60 + 61 + switch ($xaction->getTransactionType()) { 62 + case PhameBlogTransaction::TYPE_NAME: 63 + return $object->setName($xaction->getNewValue()); 64 + case PhameBlogTransaction::TYPE_DESCRIPTION: 65 + return $object->setDescription($xaction->getNewValue()); 66 + case PhameBlogTransaction::TYPE_DOMAIN: 67 + return $object->setDomain($xaction->getNewValue()); 68 + case PhameBlogTransaction::TYPE_SKIN: 69 + return $object->setSkin($xaction->getNewValue()); 70 + case PhabricatorTransactions::TYPE_VIEW_POLICY: 71 + $object->setViewPolicy($xaction->getNewValue()); 72 + return; 73 + case PhabricatorTransactions::TYPE_EDIT_POLICY: 74 + $object->setEditPolicy($xaction->getNewValue()); 75 + return; 76 + case PhabricatorTransactions::TYPE_JOIN_POLICY: 77 + $object->setJoinPolicy($xaction->getNewValue()); 78 + return; 79 + case PhabricatorTransactions::TYPE_COMMENT: 80 + return; 81 + } 82 + 83 + return parent::applyCustomInternalTransaction($object, $xaction); 84 + } 85 + 86 + protected function applyCustomExternalTransaction( 87 + PhabricatorLiskDAO $object, 88 + PhabricatorApplicationTransaction $xaction) { 89 + 90 + switch ($xaction->getTransactionType()) { 91 + case PhameBlogTransaction::TYPE_NAME: 92 + case PhameBlogTransaction::TYPE_DESCRIPTION: 93 + case PhameBlogTransaction::TYPE_DOMAIN: 94 + case PhameBlogTransaction::TYPE_SKIN: 95 + case PhabricatorTransactions::TYPE_VIEW_POLICY: 96 + case PhabricatorTransactions::TYPE_EDIT_POLICY: 97 + case PhabricatorTransactions::TYPE_JOIN_POLICY: 98 + case PhabricatorTransactions::TYPE_COMMENT: 99 + return; 100 + } 101 + 102 + return parent::applyCustomExternalTransaction($object, $xaction); 103 + } 104 + 105 + protected function validateTransaction( 106 + PhabricatorLiskDAO $object, 107 + $type, 108 + array $xactions) { 109 + 110 + $errors = parent::validateTransaction($object, $type, $xactions); 111 + 112 + switch ($type) { 113 + case PhameBlogTransaction::TYPE_NAME: 114 + $missing = $this->validateIsEmptyTextField( 115 + $object->getName(), 116 + $xactions); 117 + 118 + if ($missing) { 119 + $error = new PhabricatorApplicationTransactionValidationError( 120 + $type, 121 + pht('Required'), 122 + pht('Name is required.'), 123 + nonempty(last($xactions), null)); 124 + 125 + $error->setIsMissingFieldError(true); 126 + $errors[] = $error; 127 + } 128 + break; 129 + case PhameBlogTransaction::TYPE_DOMAIN: 130 + $custom_domain = last($xactions)->getNewValue(); 131 + if (empty($custom_domain)) { 132 + continue; 133 + } 134 + list($error_label, $error_text) = 135 + $object->validateCustomDomain($custom_domain); 136 + if ($error_label) { 137 + $error = new PhabricatorApplicationTransactionValidationError( 138 + $type, 139 + $error_label, 140 + $error_text, 141 + nonempty(last($xactions), null)); 142 + $errors[] = $error; 143 + } 144 + if ($object->getViewPolicy() != PhabricatorPolicies::POLICY_PUBLIC) { 145 + $error_text = pht( 146 + 'For custom domains to work, the blog must have a view policy of '. 147 + 'public.'); 148 + $error = new PhabricatorApplicationTransactionValidationError( 149 + PhabricatorTransactions::TYPE_VIEW_POLICY, 150 + pht('Invalid Policy'), 151 + $error_text, 152 + nonempty(last($xactions), null)); 153 + $errors[] = $error; 154 + } 155 + $duplicate_blog = id(new PhameBlogQuery()) 156 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 157 + ->withDomain($custom_domain) 158 + ->executeOne(); 159 + if ($duplicate_blog && $duplicate_blog->getID() != $object->getID()) { 160 + $error = new PhabricatorApplicationTransactionValidationError( 161 + $type, 162 + pht('Not Unique'), 163 + pht('Domain must be unique; another blog already has this domain.'), 164 + nonempty(last($xactions), null)); 165 + $errors[] = $error; 166 + } 167 + 168 + break; 169 + } 170 + return $errors; 171 + } 172 + 173 + protected function shouldSendMail( 174 + PhabricatorLiskDAO $object, 175 + array $xactions) { 176 + return false; 177 + } 178 + 179 + protected function shouldPublishFeedStory( 180 + PhabricatorLiskDAO $object, 181 + array $xactions) { 182 + return false; 183 + } 184 + 185 + protected function supportsSearch() { 186 + return false; 187 + } 188 + 189 + }
+9 -19
src/applications/phame/storage/PhameBlog.php
··· 16 16 protected $editPolicy; 17 17 protected $joinPolicy; 18 18 19 - private $bloggerPHIDs = self::ATTACHABLE; 20 - private $bloggers = self::ATTACHABLE; 21 - 22 19 static private $requestBlog; 23 20 24 21 protected function getConfiguration() { ··· 55 52 public function generatePHID() { 56 53 return PhabricatorPHID::generateNewPHID( 57 54 PhabricatorPhameBlogPHIDType::TYPECONST); 55 + } 56 + 57 + public static function initializeNewBlog(PhabricatorUser $actor) { 58 + $blog = id(new PhameBlog()) 59 + ->setCreatorPHID($actor->getPHID()) 60 + ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy()) 61 + ->setEditPolicy(PhabricatorPolicies::POLICY_USER) 62 + ->setJoinPolicy(PhabricatorPolicies::POLICY_USER); 63 + return $blog; 58 64 } 59 65 60 66 public function getSkinRenderer(AphrontRequest $request) { ··· 155 161 } 156 162 157 163 return null; 158 - } 159 - 160 - public function getBloggerPHIDs() { 161 - return $this->assertAttached($this->bloggerPHIDs); 162 - } 163 - 164 - public function attachBloggers(array $bloggers) { 165 - assert_instances_of($bloggers, 'PhabricatorObjectHandle'); 166 - 167 - $this->bloggers = $bloggers; 168 - 169 - return $this; 170 - } 171 - 172 - public function getBloggers() { 173 - return $this->assertAttached($this->bloggers); 174 164 } 175 165 176 166 public function getSkin() {
+174
src/applications/phame/storage/PhameBlogTransaction.php
··· 1 + <?php 2 + 3 + final class PhameBlogTransaction 4 + extends PhabricatorApplicationTransaction { 5 + 6 + const TYPE_NAME = 'phame.blog.name'; 7 + const TYPE_DESCRIPTION = 'phame.blog.description'; 8 + const TYPE_DOMAIN = 'phame.blog.domain'; 9 + const TYPE_SKIN = 'phame.blog.skin'; 10 + 11 + public function getApplicationName() { 12 + return 'phame'; 13 + } 14 + 15 + public function getApplicationTransactionType() { 16 + return PhabricatorPhameBlogPHIDType::TYPECONST; 17 + } 18 + 19 + public function shouldHide() { 20 + $old = $this->getOldValue(); 21 + switch ($this->getTransactionType()) { 22 + case self::TYPE_DESCRIPTION: 23 + return ($old === null); 24 + } 25 + return parent::shouldHide(); 26 + } 27 + 28 + public function getIcon() { 29 + $old = $this->getOldValue(); 30 + switch ($this->getTransactionType()) { 31 + case self::TYPE_NAME: 32 + if ($old === null) { 33 + return 'fa-plus'; 34 + } else { 35 + return 'fa-pencil'; 36 + } 37 + break; 38 + case self::TYPE_DESCRIPTION: 39 + case self::TYPE_DOMAIN: 40 + case self::TYPE_SKIN: 41 + return 'fa-pencil'; 42 + break; 43 + } 44 + return parent::getIcon(); 45 + } 46 + 47 + public function getTitle() { 48 + $author_phid = $this->getAuthorPHID(); 49 + $object_phid = $this->getObjectPHID(); 50 + 51 + $old = $this->getOldValue(); 52 + $new = $this->getNewValue(); 53 + 54 + $type = $this->getTransactionType(); 55 + switch ($type) { 56 + case self:TYPE_NAME: 57 + if ($old === null) { 58 + return pht( 59 + '%s created this blog.', 60 + $this->renderHandleLink($author_phid)); 61 + } else { 62 + return pht( 63 + '%s updated the blog\'s name to "%s".', 64 + $this->renderHandleLink($author_phid), 65 + $new); 66 + } 67 + break; 68 + case self::TYPE_DESCRIPTION: 69 + return pht( 70 + '%s updated the blog\'s description.', 71 + $this->renderHandleLink($author_phid)); 72 + break; 73 + case self::TYPE_DOMAIN: 74 + return pht( 75 + '%s updated the blog\'s domain to "%s".', 76 + $this->renderHandleLink($author_phid), 77 + $new); 78 + break; 79 + case self::TYPE_SKIN: 80 + return pht( 81 + '%s updated the blog\'s skin to "%s".', 82 + $this->renderHandleLink($author_phid), 83 + $new); 84 + break; 85 + } 86 + 87 + return parent::getTitle(); 88 + } 89 + 90 + public function getTitleForFeed() { 91 + $author_phid = $this->getAuthorPHID(); 92 + $object_phid = $this->getObjectPHID(); 93 + 94 + $old = $this->getOldValue(); 95 + $new = $this->getNewValue(); 96 + 97 + $type = $this->getTransactionType(); 98 + switch ($type) { 99 + case self::TYPE_NAME: 100 + if ($old === null) { 101 + return pht( 102 + '%s created %s.', 103 + $this->renderHandleLink($author_phid), 104 + $this->renderHandleLink($object_phid)); 105 + } else { 106 + return pht( 107 + '%s updated the name for %s.', 108 + $this->renderHandleLink($author_phid), 109 + $this->renderHandleLink($object_phid)); 110 + } 111 + break; 112 + case self::TYPE_DESCRIPTION: 113 + return pht( 114 + '%s updated the description for %s.', 115 + $this->renderHandleLink($author_phid), 116 + $this->renderHandleLink($object_phid)); 117 + break; 118 + case self::TYPE_DOMAIN: 119 + return pht( 120 + '%s updated the domain for %s.', 121 + $this->renderHandleLink($author_phid), 122 + $this->renderHandleLink($object_phid)); 123 + break; 124 + case self::TYPE_SKIN: 125 + return pht( 126 + '%s updated the skin for %s.', 127 + $this->renderHandleLink($author_phid), 128 + $this->renderHandleLink($object_phid)); 129 + break; 130 + } 131 + 132 + return parent::getTitleForFeed(); 133 + } 134 + 135 + public function getColor() { 136 + $old = $this->getOldValue(); 137 + 138 + switch ($this->getTransactionType()) { 139 + case self::TYPE_NAME: 140 + if ($old === null) { 141 + return PhabricatorTransactions::COLOR_GREEN; 142 + } 143 + break; 144 + } 145 + 146 + return parent::getColor(); 147 + } 148 + 149 + 150 + public function hasChangeDetails() { 151 + switch ($this->getTransactionType()) { 152 + case self::TYPE_DESCRIPTION: 153 + return ($this->getOldValue() !== null); 154 + } 155 + 156 + return parent::hasChangeDetails(); 157 + } 158 + 159 + public function renderChangeDetails(PhabricatorUser $viewer) { 160 + switch ($this->getTransactionType()) { 161 + case self::TYPE_DESCRIPTION: 162 + $old = $this->getOldValue(); 163 + $new = $this->getNewValue(); 164 + 165 + return $this->renderTextCorpusChangeDetails( 166 + $viewer, 167 + $old, 168 + $new); 169 + } 170 + 171 + return parent::renderChangeDetails($viewer); 172 + } 173 + 174 + }