From 21ac19630613d1bc804827d11dac83b8571ff485 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Tue, 2 May 2017 15:11:54 -0700 Subject: [PATCH] Modernize PhameBlog with modular transactions Summary: Moves PhameBlog over to the wonderful world of modular transactions and the riches that lay beyond... Test Plan: - Create Blog - Edit Blog - Set Header - Delete Header - Add picture - Archive blog - Set incorrect domain values - Be irresponsible with subtitle length - Activate blog - Change description Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D17815 --- src/__phutil_library_map__.php | 22 +- .../blog/PhameBlogArchiveController.php | 2 +- .../blog/PhameBlogHeaderPictureController.php | 2 +- .../PhameBlogProfilePictureController.php | 3 +- .../phame/editor/PhameBlogEditEngine.php | 14 +- .../phame/editor/PhameBlogEditor.php | 245 +------------ src/applications/phame/storage/PhameBlog.php | 44 +-- .../phame/storage/PhameBlogTransaction.php | 327 +----------------- .../PhameBlogDescriptionTransaction.php | 60 ++++ .../PhameBlogFullDomainTransaction.php | 95 +++++ .../PhameBlogHeaderImageTransaction.php | 34 ++ .../xaction/PhameBlogNameTransaction.php | 59 ++++ .../PhameBlogParentDomainTransaction.php | 82 +++++ .../PhameBlogParentSiteTransaction.php | 66 ++++ .../PhameBlogProfileImageTransaction.php | 34 ++ .../xaction/PhameBlogStatusTransaction.php | 55 +++ .../xaction/PhameBlogSubtitleTransaction.php | 63 ++++ .../xaction/PhameBlogTransactionType.php | 4 + 18 files changed, 611 insertions(+), 600 deletions(-) create mode 100644 src/applications/phame/xaction/PhameBlogDescriptionTransaction.php create mode 100644 src/applications/phame/xaction/PhameBlogFullDomainTransaction.php create mode 100644 src/applications/phame/xaction/PhameBlogHeaderImageTransaction.php create mode 100644 src/applications/phame/xaction/PhameBlogNameTransaction.php create mode 100644 src/applications/phame/xaction/PhameBlogParentDomainTransaction.php create mode 100644 src/applications/phame/xaction/PhameBlogParentSiteTransaction.php create mode 100644 src/applications/phame/xaction/PhameBlogProfileImageTransaction.php create mode 100644 src/applications/phame/xaction/PhameBlogStatusTransaction.php create mode 100644 src/applications/phame/xaction/PhameBlogSubtitleTransaction.php create mode 100644 src/applications/phame/xaction/PhameBlogTransactionType.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 86dd5a00d8..0c71c8eab1 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4232,24 +4232,34 @@ phutil_register_library_map(array( 'PhameBlogController' => 'applications/phame/controller/blog/PhameBlogController.php', 'PhameBlogCreateCapability' => 'applications/phame/capability/PhameBlogCreateCapability.php', 'PhameBlogDatasource' => 'applications/phame/typeahead/PhameBlogDatasource.php', + 'PhameBlogDescriptionTransaction' => 'applications/phame/xaction/PhameBlogDescriptionTransaction.php', 'PhameBlogEditConduitAPIMethod' => 'applications/phame/conduit/PhameBlogEditConduitAPIMethod.php', 'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php', 'PhameBlogEditEngine' => 'applications/phame/editor/PhameBlogEditEngine.php', 'PhameBlogEditor' => 'applications/phame/editor/PhameBlogEditor.php', 'PhameBlogFeedController' => 'applications/phame/controller/blog/PhameBlogFeedController.php', + 'PhameBlogFullDomainTransaction' => 'applications/phame/xaction/PhameBlogFullDomainTransaction.php', 'PhameBlogFulltextEngine' => 'applications/phame/search/PhameBlogFulltextEngine.php', + 'PhameBlogHeaderImageTransaction' => 'applications/phame/xaction/PhameBlogHeaderImageTransaction.php', 'PhameBlogHeaderPictureController' => 'applications/phame/controller/blog/PhameBlogHeaderPictureController.php', 'PhameBlogListController' => 'applications/phame/controller/blog/PhameBlogListController.php', 'PhameBlogListView' => 'applications/phame/view/PhameBlogListView.php', 'PhameBlogManageController' => 'applications/phame/controller/blog/PhameBlogManageController.php', + 'PhameBlogNameTransaction' => 'applications/phame/xaction/PhameBlogNameTransaction.php', + 'PhameBlogParentDomainTransaction' => 'applications/phame/xaction/PhameBlogParentDomainTransaction.php', + 'PhameBlogParentSiteTransaction' => 'applications/phame/xaction/PhameBlogParentSiteTransaction.php', + 'PhameBlogProfileImageTransaction' => 'applications/phame/xaction/PhameBlogProfileImageTransaction.php', 'PhameBlogProfilePictureController' => 'applications/phame/controller/blog/PhameBlogProfilePictureController.php', 'PhameBlogQuery' => 'applications/phame/query/PhameBlogQuery.php', 'PhameBlogReplyHandler' => 'applications/phame/mail/PhameBlogReplyHandler.php', 'PhameBlogSearchConduitAPIMethod' => 'applications/phame/conduit/PhameBlogSearchConduitAPIMethod.php', 'PhameBlogSearchEngine' => 'applications/phame/query/PhameBlogSearchEngine.php', 'PhameBlogSite' => 'applications/phame/site/PhameBlogSite.php', + 'PhameBlogStatusTransaction' => 'applications/phame/xaction/PhameBlogStatusTransaction.php', + 'PhameBlogSubtitleTransaction' => 'applications/phame/xaction/PhameBlogSubtitleTransaction.php', 'PhameBlogTransaction' => 'applications/phame/storage/PhameBlogTransaction.php', 'PhameBlogTransactionQuery' => 'applications/phame/query/PhameBlogTransactionQuery.php', + 'PhameBlogTransactionType' => 'applications/phame/xaction/PhameBlogTransactionType.php', 'PhameBlogViewController' => 'applications/phame/controller/blog/PhameBlogViewController.php', 'PhameConstants' => 'applications/phame/constants/PhameConstants.php', 'PhameController' => 'applications/phame/controller/PhameController.php', @@ -9690,24 +9700,34 @@ phutil_register_library_map(array( 'PhameBlogController' => 'PhameController', 'PhameBlogCreateCapability' => 'PhabricatorPolicyCapability', 'PhameBlogDatasource' => 'PhabricatorTypeaheadDatasource', + 'PhameBlogDescriptionTransaction' => 'PhameBlogTransactionType', 'PhameBlogEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 'PhameBlogEditController' => 'PhameBlogController', 'PhameBlogEditEngine' => 'PhabricatorEditEngine', 'PhameBlogEditor' => 'PhabricatorApplicationTransactionEditor', 'PhameBlogFeedController' => 'PhameBlogController', + 'PhameBlogFullDomainTransaction' => 'PhameBlogTransactionType', 'PhameBlogFulltextEngine' => 'PhabricatorFulltextEngine', + 'PhameBlogHeaderImageTransaction' => 'PhameBlogTransactionType', 'PhameBlogHeaderPictureController' => 'PhameBlogController', 'PhameBlogListController' => 'PhameBlogController', 'PhameBlogListView' => 'AphrontTagView', 'PhameBlogManageController' => 'PhameBlogController', + 'PhameBlogNameTransaction' => 'PhameBlogTransactionType', + 'PhameBlogParentDomainTransaction' => 'PhameBlogTransactionType', + 'PhameBlogParentSiteTransaction' => 'PhameBlogTransactionType', + 'PhameBlogProfileImageTransaction' => 'PhameBlogTransactionType', 'PhameBlogProfilePictureController' => 'PhameBlogController', 'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhameBlogReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 'PhameBlogSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 'PhameBlogSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhameBlogSite' => 'PhameSite', - 'PhameBlogTransaction' => 'PhabricatorApplicationTransaction', + 'PhameBlogStatusTransaction' => 'PhameBlogTransactionType', + 'PhameBlogSubtitleTransaction' => 'PhameBlogTransactionType', + 'PhameBlogTransaction' => 'PhabricatorModularTransaction', 'PhameBlogTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'PhameBlogTransactionType' => 'PhabricatorModularTransactionType', 'PhameBlogViewController' => 'PhameLiveController', 'PhameConstants' => 'Phobject', 'PhameController' => 'PhabricatorController', diff --git a/src/applications/phame/controller/blog/PhameBlogArchiveController.php b/src/applications/phame/controller/blog/PhameBlogArchiveController.php index 4c8d4a4a63..8b63bad9ff 100644 --- a/src/applications/phame/controller/blog/PhameBlogArchiveController.php +++ b/src/applications/phame/controller/blog/PhameBlogArchiveController.php @@ -32,7 +32,7 @@ final class PhameBlogArchiveController $xactions = array(); $xactions[] = id(new PhameBlogTransaction()) - ->setTransactionType(PhameBlogTransaction::TYPE_STATUS) + ->setTransactionType(PhameBlogStatusTransaction::TRANSACTIONTYPE) ->setNewValue($new_status); id(new PhameBlogEditor()) diff --git a/src/applications/phame/controller/blog/PhameBlogHeaderPictureController.php b/src/applications/phame/controller/blog/PhameBlogHeaderPictureController.php index ab026fecbf..0106b9571d 100644 --- a/src/applications/phame/controller/blog/PhameBlogHeaderPictureController.php +++ b/src/applications/phame/controller/blog/PhameBlogHeaderPictureController.php @@ -61,7 +61,7 @@ final class PhameBlogHeaderPictureController $xactions = array(); $xactions[] = id(new PhameBlogTransaction()) - ->setTransactionType(PhameBlogTransaction::TYPE_HEADERIMAGE) + ->setTransactionType(PhameBlogHeaderImageTransaction::TRANSACTIONTYPE) ->setNewValue($new_value); $editor = id(new PhameBlogEditor()) diff --git a/src/applications/phame/controller/blog/PhameBlogProfilePictureController.php b/src/applications/phame/controller/blog/PhameBlogProfilePictureController.php index 3368046414..04b41dbb79 100644 --- a/src/applications/phame/controller/blog/PhameBlogProfilePictureController.php +++ b/src/applications/phame/controller/blog/PhameBlogProfilePictureController.php @@ -76,7 +76,8 @@ final class PhameBlogProfilePictureController $xactions = array(); $xactions[] = id(new PhameBlogTransaction()) - ->setTransactionType(PhameBlogTransaction::TYPE_PROFILEIMAGE) + ->setTransactionType( + PhameBlogProfileImageTransaction::TRANSACTIONTYPE) ->setNewValue($new_value); $editor = id(new PhameBlogEditor()) diff --git a/src/applications/phame/editor/PhameBlogEditEngine.php b/src/applications/phame/editor/PhameBlogEditEngine.php index 7d6511d55c..6d6c0a9f77 100644 --- a/src/applications/phame/editor/PhameBlogEditEngine.php +++ b/src/applications/phame/editor/PhameBlogEditEngine.php @@ -75,7 +75,7 @@ final class PhameBlogEditEngine ->setDescription(pht('Blog name.')) ->setConduitDescription(pht('Retitle the blog.')) ->setConduitTypeDescription(pht('New blog title.')) - ->setTransactionType(PhameBlogTransaction::TYPE_NAME) + ->setTransactionType(PhameBlogNameTransaction::TRANSACTIONTYPE) ->setValue($object->getName()), id(new PhabricatorTextEditField()) ->setKey('subtitle') @@ -83,7 +83,7 @@ final class PhameBlogEditEngine ->setDescription(pht('Blog subtitle.')) ->setConduitDescription(pht('Change the blog subtitle.')) ->setConduitTypeDescription(pht('New blog subtitle.')) - ->setTransactionType(PhameBlogTransaction::TYPE_SUBTITLE) + ->setTransactionType(PhameBlogSubtitleTransaction::TRANSACTIONTYPE) ->setValue($object->getSubtitle()), id(new PhabricatorRemarkupEditField()) ->setKey('description') @@ -91,7 +91,7 @@ final class PhameBlogEditEngine ->setDescription(pht('Blog description.')) ->setConduitDescription(pht('Change the blog description.')) ->setConduitTypeDescription(pht('New blog description.')) - ->setTransactionType(PhameBlogTransaction::TYPE_DESCRIPTION) + ->setTransactionType(PhameBlogDescriptionTransaction::TRANSACTIONTYPE) ->setValue($object->getDescription()), id(new PhabricatorTextEditField()) ->setKey('domainFullURI') @@ -104,7 +104,7 @@ final class PhameBlogEditEngine ->setConduitDescription(pht('Change the blog full domain URI.')) ->setConduitTypeDescription(pht('New blog full domain URI.')) ->setValue($object->getDomainFullURI()) - ->setTransactionType(PhameBlogTransaction::TYPE_FULLDOMAIN), + ->setTransactionType(PhameBlogFullDomainTransaction::TRANSACTIONTYPE), id(new PhabricatorTextEditField()) ->setKey('parentSite') ->setLabel(pht('Parent Site Name')) @@ -112,7 +112,7 @@ final class PhameBlogEditEngine ->setConduitDescription(pht('Change the blog parent site name.')) ->setConduitTypeDescription(pht('New blog parent site name.')) ->setValue($object->getParentSite()) - ->setTransactionType(PhameBlogTransaction::TYPE_PARENTSITE), + ->setTransactionType(PhameBlogParentSiteTransaction::TRANSACTIONTYPE), id(new PhabricatorTextEditField()) ->setKey('parentDomain') ->setLabel(pht('Parent Site URI')) @@ -120,11 +120,11 @@ final class PhameBlogEditEngine ->setConduitDescription(pht('Change the blog parent domain.')) ->setConduitTypeDescription(pht('New blog parent domain.')) ->setValue($object->getParentDomain()) - ->setTransactionType(PhameBlogTransaction::TYPE_PARENTDOMAIN), + ->setTransactionType(PhameBlogParentDomainTransaction::TRANSACTIONTYPE), id(new PhabricatorSelectEditField()) ->setKey('status') ->setLabel(pht('Status')) - ->setTransactionType(PhameBlogTransaction::TYPE_STATUS) + ->setTransactionType(PhameBlogStatusTransaction::TRANSACTIONTYPE) ->setIsConduitOnly(true) ->setOptions(PhameBlog::getStatusNameMap()) ->setDescription(pht('Active or archived status.')) diff --git a/src/applications/phame/editor/PhameBlogEditor.php b/src/applications/phame/editor/PhameBlogEditor.php index 14f63f51ac..f30a74065e 100644 --- a/src/applications/phame/editor/PhameBlogEditor.php +++ b/src/applications/phame/editor/PhameBlogEditor.php @@ -11,251 +11,22 @@ final class PhameBlogEditor return pht('Phame Blogs'); } + public function getCreateObjectTitle($author, $object) { + return pht('%s created this blog.', $author); + } + + public function getCreateObjectTitleForFeed($author, $object) { + return pht('%s created %s.', $author, $object); + } + public function getTransactionTypes() { $types = parent::getTransactionTypes(); - - $types[] = PhameBlogTransaction::TYPE_NAME; - $types[] = PhameBlogTransaction::TYPE_SUBTITLE; - $types[] = PhameBlogTransaction::TYPE_DESCRIPTION; - $types[] = PhameBlogTransaction::TYPE_FULLDOMAIN; - $types[] = PhameBlogTransaction::TYPE_PARENTSITE; - $types[] = PhameBlogTransaction::TYPE_PARENTDOMAIN; - $types[] = PhameBlogTransaction::TYPE_STATUS; - $types[] = PhameBlogTransaction::TYPE_HEADERIMAGE; - $types[] = PhameBlogTransaction::TYPE_PROFILEIMAGE; - $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; return $types; } - protected function getCustomTransactionOldValue( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhameBlogTransaction::TYPE_NAME: - return $object->getName(); - case PhameBlogTransaction::TYPE_SUBTITLE: - return $object->getSubtitle(); - case PhameBlogTransaction::TYPE_DESCRIPTION: - return $object->getDescription(); - case PhameBlogTransaction::TYPE_FULLDOMAIN: - return $object->getDomainFullURI(); - case PhameBlogTransaction::TYPE_PARENTSITE: - return $object->getParentSite(); - case PhameBlogTransaction::TYPE_PARENTDOMAIN: - return $object->getParentDomain(); - case PhameBlogTransaction::TYPE_PROFILEIMAGE: - return $object->getProfileImagePHID(); - case PhameBlogTransaction::TYPE_HEADERIMAGE: - return $object->getHeaderImagePHID(); - case PhameBlogTransaction::TYPE_STATUS: - return $object->getStatus(); - } - } - - protected function getCustomTransactionNewValue( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhameBlogTransaction::TYPE_NAME: - case PhameBlogTransaction::TYPE_SUBTITLE: - case PhameBlogTransaction::TYPE_DESCRIPTION: - case PhameBlogTransaction::TYPE_STATUS: - case PhameBlogTransaction::TYPE_PARENTSITE: - case PhameBlogTransaction::TYPE_PARENTDOMAIN: - case PhameBlogTransaction::TYPE_PROFILEIMAGE: - case PhameBlogTransaction::TYPE_HEADERIMAGE: - return $xaction->getNewValue(); - case PhameBlogTransaction::TYPE_FULLDOMAIN: - $domain = $xaction->getNewValue(); - if (!strlen($xaction->getNewValue())) { - return null; - } - return $domain; - } - } - - protected function applyCustomInternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhameBlogTransaction::TYPE_NAME: - return $object->setName($xaction->getNewValue()); - case PhameBlogTransaction::TYPE_SUBTITLE: - return $object->setSubtitle($xaction->getNewValue()); - case PhameBlogTransaction::TYPE_DESCRIPTION: - return $object->setDescription($xaction->getNewValue()); - case PhameBlogTransaction::TYPE_FULLDOMAIN: - $new_value = $xaction->getNewValue(); - if (strlen($new_value)) { - $uri = new PhutilURI($new_value); - $domain = $uri->getDomain(); - $object->setDomain($domain); - } else { - $object->setDomain(null); - } - $object->setDomainFullURI($new_value); - return; - case PhameBlogTransaction::TYPE_PROFILEIMAGE: - return $object->setProfileImagePHID($xaction->getNewValue()); - case PhameBlogTransaction::TYPE_HEADERIMAGE: - return $object->setHeaderImagePHID($xaction->getNewValue()); - case PhameBlogTransaction::TYPE_STATUS: - return $object->setStatus($xaction->getNewValue()); - case PhameBlogTransaction::TYPE_PARENTSITE: - return $object->setParentSite($xaction->getNewValue()); - case PhameBlogTransaction::TYPE_PARENTDOMAIN: - return $object->setParentDomain($xaction->getNewValue()); - } - - return parent::applyCustomInternalTransaction($object, $xaction); - } - - protected function applyCustomExternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhameBlogTransaction::TYPE_NAME: - case PhameBlogTransaction::TYPE_SUBTITLE: - case PhameBlogTransaction::TYPE_DESCRIPTION: - case PhameBlogTransaction::TYPE_FULLDOMAIN: - case PhameBlogTransaction::TYPE_PARENTSITE: - case PhameBlogTransaction::TYPE_PARENTDOMAIN: - case PhameBlogTransaction::TYPE_HEADERIMAGE: - case PhameBlogTransaction::TYPE_PROFILEIMAGE: - case PhameBlogTransaction::TYPE_STATUS: - 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; - } - - foreach ($xactions as $xaction) { - $new = $xaction->getNewValue(); - if (phutil_utf8_strlen($new) > 64) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'The selected blog title is too long. The maximum length '. - 'of a blog title is 64 characters.'), - $xaction); - } - } - break; - case PhameBlogTransaction::TYPE_SUBTITLE: - foreach ($xactions as $xaction) { - $new = $xaction->getNewValue(); - if (phutil_utf8_strlen($new) > 64) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'The selected blog subtitle is too long. The maximum length '. - 'of a blog subtitle is 64 characters.'), - $xaction); - } - } - break; - case PhameBlogTransaction::TYPE_PARENTDOMAIN: - if (!$xactions) { - continue; - } - $parent_domain = last($xactions)->getNewValue(); - if (empty($parent_domain)) { - continue; - } - try { - PhabricatorEnv::requireValidRemoteURIForLink($parent_domain); - } catch (Exception $ex) { - $error = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid URI'), - pht('Parent Domain must be set to a valid Remote URI.'), - nonempty(last($xactions), null)); - $errors[] = $error; - } - break; - case PhameBlogTransaction::TYPE_FULLDOMAIN: - if (!$xactions) { - continue; - } - $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; - } - $domain = new PhutilURI($custom_domain); - $domain = $domain->getDomain(); - $duplicate_blog = id(new PhameBlogQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withDomain($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) { diff --git a/src/applications/phame/storage/PhameBlog.php b/src/applications/phame/storage/PhameBlog.php index bd4954d0ab..b72fc4bcfe 100644 --- a/src/applications/phame/storage/PhameBlog.php +++ b/src/applications/phame/storage/PhameBlog.php @@ -127,53 +127,41 @@ final class PhameBlog extends PhameDAO $supported_protocols = array('http', 'https'); if (!in_array($protocol, $supported_protocols)) { - return array( - $label, - pht( + return pht( 'The custom domain should include a valid protocol in the URI '. '(for example, "%s"). Valid protocols are "http" or "https".', - $example_domain), - ); + $example_domain); } if (strlen($path) && $path != '/') { - return array( - $label, - pht( + return pht( 'The custom domain should not specify a path (hosting a Phame '. 'blog at a path is currently not supported). Instead, just provide '. 'the bare domain name (for example, "%s").', - $example_domain), - ); + $example_domain); } if (strpos($domain, '.') === false) { - return array( - $label, - pht( + return pht( 'The custom domain should contain at least one dot (.) because '. 'some browsers fail to set cookies on domains without a dot. '. 'Instead, use a normal looking domain name like "%s".', - $example_domain), - ); + $example_domain); } if (!PhabricatorEnv::getEnvConfig('policy.allow-public')) { $href = PhabricatorEnv::getProductionURI( '/config/edit/policy.allow-public/'); - return array( - pht('Fix Configuration'), - pht( - 'For custom domains to work, this Phabricator instance must be '. - 'configured to allow the public access policy. Configure this '. - 'setting %s, or ask an administrator to configure this setting. '. - 'The domain can be specified later once this setting has been '. - 'changed.', - phutil_tag( - 'a', - array('href' => $href), - pht('here'))), - ); + return pht( + 'For custom domains to work, this Phabricator instance must be '. + 'configured to allow the public access policy. Configure this '. + 'setting %s, or ask an administrator to configure this setting. '. + 'The domain can be specified later once this setting has been '. + 'changed.', + phutil_tag( + 'a', + array('href' => $href), + pht('here'))); } return null; diff --git a/src/applications/phame/storage/PhameBlogTransaction.php b/src/applications/phame/storage/PhameBlogTransaction.php index f08c7be688..c5702a2b18 100644 --- a/src/applications/phame/storage/PhameBlogTransaction.php +++ b/src/applications/phame/storage/PhameBlogTransaction.php @@ -1,17 +1,7 @@ getOldValue(); - switch ($this->getTransactionType()) { - case self::TYPE_DESCRIPTION: - if ($old === null) { - return true; - } - } - return parent::shouldHide(); - } - - public function getRequiredHandlePHIDs() { - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - $req_phids = array(); - switch ($this->getTransactionType()) { - case self::TYPE_PROFILEIMAGE: - case self::TYPE_HEADERIMAGE: - $req_phids[] = $old; - $req_phids[] = $new; - break; - } - - return array_merge($req_phids, parent::getRequiredHandlePHIDs()); - } - - public function getIcon() { - $old = $this->getOldValue(); - $new = $this->getNewValue(); - 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_FULLDOMAIN: - return 'fa-pencil'; - case self::TYPE_HEADERIMAGE: - return 'fa-image'; - case self::TYPE_PROFILEIMAGE: - return 'fa-star'; - case self::TYPE_STATUS: - if ($new == PhameBlog::STATUS_ARCHIVED) { - return 'fa-ban'; - } else { - return 'fa-check'; - } - break; - } - return parent::getIcon(); - } - - public function getColor() { - - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - switch ($this->getTransactionType()) { - case self::TYPE_STATUS: - if ($new == PhameBlog::STATUS_ARCHIVED) { - return 'violet'; - } else { - return 'green'; - } - } - return parent::getColor(); + public function getBaseTransactionClass() { + return 'PhameBlogTransactionType'; } public function getMailTags() { @@ -121,247 +43,4 @@ final class PhameBlogTransaction return $tags; } - public function getTitle() { - $author_phid = $this->getAuthorPHID(); - $object_phid = $this->getObjectPHID(); - - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - $type = $this->getTransactionType(); - switch ($type) { - case PhabricatorTransactions::TYPE_CREATE: - return pht( - '%s created this blog.', - $this->renderHandleLink($author_phid)); - 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_SUBTITLE: - if ($old === null) { - return pht( - '%s set this blog\'s subtitle to "%s".', - $this->renderHandleLink($author_phid), - $new); - } else { - return pht( - '%s updated the blog\'s subtitle 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_FULLDOMAIN: - return pht( - '%s updated the blog\'s full domain to "%s".', - $this->renderHandleLink($author_phid), - $new); - break; - case self::TYPE_PARENTSITE: - if ($old === null) { - return pht( - '%s set this blog\'s parent site to "%s".', - $this->renderHandleLink($author_phid), - $new); - } else { - return pht( - '%s updated the blog\'s parent site to "%s".', - $this->renderHandleLink($author_phid), - $new); - } - break; - case self::TYPE_PARENTDOMAIN: - if ($old === null) { - return pht( - '%s set this blog\'s parent domain to "%s".', - $this->renderHandleLink($author_phid), - $new); - } else { - return pht( - '%s updated the blog\'s parent domain to "%s".', - $this->renderHandleLink($author_phid), - $new); - } - break; - case self::TYPE_HEADERIMAGE: - if (!$old) { - return pht( - "%s set this blog's header image to %s.", - $this->renderHandleLink($author_phid), - $this->renderHandleLink($new)); - } else if (!$new) { - return pht( - "%s removed this blog's header image.", - $this->renderHandleLink($author_phid)); - } else { - return pht( - "%s updated this blog's header image from %s to %s.", - $this->renderHandleLink($author_phid), - $this->renderHandleLink($old), - $this->renderHandleLink($new)); - } - break; - case self::TYPE_PROFILEIMAGE: - if (!$old) { - return pht( - "%s set this blog's profile image to %s.", - $this->renderHandleLink($author_phid), - $this->renderHandleLink($new)); - } else if (!$new) { - return pht( - "%s removed this blog's profile image.", - $this->renderHandleLink($author_phid)); - } else { - return pht( - "%s updated this blog's profile image from %s to %s.", - $this->renderHandleLink($author_phid), - $this->renderHandleLink($old), - $this->renderHandleLink($new)); - } - break; - case self::TYPE_STATUS: - switch ($new) { - case PhameBlog::STATUS_ACTIVE: - return pht( - '%s published this blog.', - $this->renderHandleLink($author_phid)); - case PhameBlog::STATUS_ARCHIVED: - return pht( - '%s archived this blog.', - $this->renderHandleLink($author_phid)); - } - - } - - 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_SUBTITLE: - if ($old === null) { - return pht( - '%s set the subtitle for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - } else { - return pht( - '%s updated the subtitle 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_FULLDOMAIN: - return pht( - '%s updated the full domain for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - break; - case self::TYPE_PARENTSITE: - return pht( - '%s updated the parent site for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - break; - case self::TYPE_PARENTDOMAIN: - return pht( - '%s updated the parent domain for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - break; - case self::TYPE_HEADERIMAGE: - return pht( - '%s updated the header image for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - break; - case self::TYPE_PROFILEIMAGE: - return pht( - '%s updated the profile image for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - break; - case self::TYPE_STATUS: - switch ($new) { - case PhameBlog::STATUS_ACTIVE: - return pht( - '%s published the blog %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - case PhameBlog::STATUS_ARCHIVED: - return pht( - '%s archived the blog %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); - } - break; - - } - - return parent::getTitleForFeed(); - } - - 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); - } - } diff --git a/src/applications/phame/xaction/PhameBlogDescriptionTransaction.php b/src/applications/phame/xaction/PhameBlogDescriptionTransaction.php new file mode 100644 index 0000000000..2bc12f3998 --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogDescriptionTransaction.php @@ -0,0 +1,60 @@ +getDescription(); + } + + public function applyInternalEffects($object, $value) { + $object->setDescription($value); + } + + public function getTitle() { + return pht( + '%s updated the description.', + $this->renderAuthor()); + } + + public function getTitleForFeed() { + return pht( + '%s updated the description for %s.', + $this->renderAuthor(), + $this->renderObject()); + } + + public function hasChangeDetailView() { + return true; + } + + public function getMailDiffSectionHeader() { + return pht('CHANGES TO BLOG DESCRIPTION'); + } + + public function newChangeDetailView() { + $viewer = $this->getViewer(); + + return id(new PhabricatorApplicationTransactionTextDiffDetailView()) + ->setViewer($viewer) + ->setOldText($this->getOldValue()) + ->setNewText($this->getNewValue()); + } + + public function newRemarkupChanges() { + $changes = array(); + + $changes[] = $this->newRemarkupChange() + ->setOldValue($this->getOldValue()) + ->setNewValue($this->getNewValue()); + + return $changes; + } + + public function getIcon() { + return 'fa-file-text-o'; + } + +} diff --git a/src/applications/phame/xaction/PhameBlogFullDomainTransaction.php b/src/applications/phame/xaction/PhameBlogFullDomainTransaction.php new file mode 100644 index 0000000000..5287f9cc06 --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogFullDomainTransaction.php @@ -0,0 +1,95 @@ +getDomainFullURI(); + } + + public function applyInternalEffects($object, $value) { + if (strlen($value)) { + $uri = new PhutilURI($value); + $domain = $uri->getDomain(); + $object->setDomain($domain); + } else { + $object->setDomain(null); + } + $object->setDomainFullURI($value); + } + + public function getTitle() { + $old = $this->getOldValue(); + if (!strlen($old)) { + return pht( + '%s set this blog\'s full domain to %s.', + $this->renderAuthor(), + $this->renderNewValue()); + } else { + return pht( + '%s updated the blog\'s full domain from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function getTitleForFeed() { + $old = $this->getOldValue(); + if (!strlen($old)) { + return pht( + '%s set %s blog\'s full domain to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderNewValue()); + } else { + return pht( + '%s updated %s blog\'s full domain from %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if (!$xactions) { + return $errors; + } + + $custom_domain = last($xactions)->getNewValue(); + if (empty($custom_domain)) { + return $errors; + } + + $error_text = $object->validateCustomDomain($custom_domain); + if ($error_text) { + $errors[] = $this->newInvalidError($error_text); + } + + if ($object->getViewPolicy() != PhabricatorPolicies::POLICY_PUBLIC) { + $errors[] = $this->newInvalidError( + pht('For custom domains to work, the blog must have a view policy of '. + 'public. This blog is currently set to "%s".', + $object->getViewPolicy())); + } + + $domain = new PhutilURI($custom_domain); + $domain = $domain->getDomain(); + $duplicate_blog = id(new PhameBlogQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withDomain($domain) + ->executeOne(); + if ($duplicate_blog && $duplicate_blog->getID() != $object->getID()) { + $errors[] = $this->newInvalidError( + pht('Domain must be unique; another blog already has this domain.')); + } + + return $errors; + } + +} diff --git a/src/applications/phame/xaction/PhameBlogHeaderImageTransaction.php b/src/applications/phame/xaction/PhameBlogHeaderImageTransaction.php new file mode 100644 index 0000000000..b328b9aca5 --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogHeaderImageTransaction.php @@ -0,0 +1,34 @@ +getHeaderImagePHID(); + } + + public function applyInternalEffects($object, $value) { + $object->setHeaderImagePHID($value); + } + + public function getTitle() { + return pht( + '%s changed the header image for this blog.', + $this->renderAuthor()); + } + + public function getTitleForFeed() { + return pht( + '%s changed the header image for blog %s.', + $this->renderAuthor(), + $this->renderObject()); + } + + public function getIcon() { + return 'fa-camera'; + } + +} diff --git a/src/applications/phame/xaction/PhameBlogNameTransaction.php b/src/applications/phame/xaction/PhameBlogNameTransaction.php new file mode 100644 index 0000000000..dbca5304a8 --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogNameTransaction.php @@ -0,0 +1,59 @@ +getName(); + } + + public function applyInternalEffects($object, $value) { + $object->setName($value); + } + + public function getTitle() { + return pht( + '%s renamed this blog from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function getTitleForFeed() { + return pht( + '%s renamed %s blog froms %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if ($this->isEmptyTextTransaction($object->getName(), $xactions)) { + $errors[] = $this->newRequiredError( + pht('Blogs must have a name.')); + } + + $max_length = $object->getColumnMaximumByteLength('name'); + foreach ($xactions as $xaction) { + $new_value = $xaction->getNewValue(); + $new_length = strlen($new_value); + if ($new_length > $max_length) { + $errors[] = $this->newInvalidError( + pht('The name can be no longer than %s characters.', + new PhutilNumber($max_length))); + } + } + + return $errors; + } + + public function getIcon() { + return 'fa-rss'; + } + +} diff --git a/src/applications/phame/xaction/PhameBlogParentDomainTransaction.php b/src/applications/phame/xaction/PhameBlogParentDomainTransaction.php new file mode 100644 index 0000000000..227c8ce8c3 --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogParentDomainTransaction.php @@ -0,0 +1,82 @@ +getParentDomain(); + } + + public function applyInternalEffects($object, $value) { + $object->setParentDomain($value); + } + + public function getTitle() { + $old = $this->getOldValue(); + if (!strlen($old)) { + return pht( + '%s set this blog\'s parent domain to %s.', + $this->renderAuthor(), + $this->renderNewValue()); + } else { + return pht( + '%s updated the blog\'s parent domain from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function getTitleForFeed() { + $old = $this->getOldValue(); + if (!strlen($old)) { + return pht( + '%s set %s blog\'s parent domain to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderNewValue()); + } else { + return pht( + '%s updated %s blog\'s parent domain from %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if (!$xactions) { + return $errors; + } + + $parent_domain = last($xactions)->getNewValue(); + if (empty($parent_domain)) { + return $errors; + } + + try { + PhabricatorEnv::requireValidRemoteURIForLink($parent_domain); + } catch (Exception $ex) { + $errors[] = $this->newInvalidError( + pht('Parent Domain must be set to a valid Remote URI.')); + } + + $max_length = $object->getColumnMaximumByteLength('parentDomain'); + foreach ($xactions as $xaction) { + $new_value = $xaction->getNewValue(); + $new_length = strlen($new_value); + if ($new_length > $max_length) { + $errors[] = $this->newInvalidError( + pht('The parent domain can be no longer than %s characters.', + new PhutilNumber($max_length))); + } + } + + return $errors; + } +} diff --git a/src/applications/phame/xaction/PhameBlogParentSiteTransaction.php b/src/applications/phame/xaction/PhameBlogParentSiteTransaction.php new file mode 100644 index 0000000000..1b62b98488 --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogParentSiteTransaction.php @@ -0,0 +1,66 @@ +getParentSite(); + } + + public function applyInternalEffects($object, $value) { + $object->setParentSite($value); + } + + public function getTitle() { + $old = $this->getOldValue(); + if (!strlen($old)) { + return pht( + '%s set this blog\'s parent site to %s.', + $this->renderAuthor(), + $this->renderNewValue()); + } else { + return pht( + '%s updated the blog\'s parent site from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function getTitleForFeed() { + $old = $this->getOldValue(); + if (!strlen($old)) { + return pht( + '%s set %s blog\'s parent site to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderNewValue()); + } else { + return pht( + '%s updated %s blog\'s parent site from %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + $max_length = $object->getColumnMaximumByteLength('parentSite'); + foreach ($xactions as $xaction) { + $new_value = $xaction->getNewValue(); + $new_length = strlen($new_value); + if ($new_length > $max_length) { + $errors[] = $this->newInvalidError( + pht('The parent site can be no longer than %s characters.', + new PhutilNumber($max_length))); + } + } + + return $errors; + } +} diff --git a/src/applications/phame/xaction/PhameBlogProfileImageTransaction.php b/src/applications/phame/xaction/PhameBlogProfileImageTransaction.php new file mode 100644 index 0000000000..77acf680fd --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogProfileImageTransaction.php @@ -0,0 +1,34 @@ +getProfileImagePHID(); + } + + public function applyInternalEffects($object, $value) { + $object->setProfileImagePHID($value); + } + + public function getTitle() { + return pht( + '%s changed the profile image for this blog.', + $this->renderAuthor()); + } + + public function getTitleForFeed() { + return pht( + '%s changed the profile image for blog %s.', + $this->renderAuthor(), + $this->renderObject()); + } + + public function getIcon() { + return 'fa-file-image-o'; + } + +} diff --git a/src/applications/phame/xaction/PhameBlogStatusTransaction.php b/src/applications/phame/xaction/PhameBlogStatusTransaction.php new file mode 100644 index 0000000000..21345ea249 --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogStatusTransaction.php @@ -0,0 +1,55 @@ +getStatus(); + } + + public function applyInternalEffects($object, $value) { + $object->setStatus($value); + } + + public function getTitle() { + $new = $this->getNewValue(); + switch ($new) { + case PhameBlog::STATUS_ACTIVE: + return pht( + '%s published this blog.', + $this->renderAuthor()); + case PhameBlog::STATUS_ARCHIVED: + return pht( + '%s archived this blog.', + $this->renderAuthor()); + } + } + + public function getTitleForFeed() { + $new = $this->getNewValue(); + switch ($new) { + case PhameBlog::STATUS_ACTIVE: + return pht( + '%s published the blog %s.', + $this->renderAuthor(), + $this->renderObject()); + case PhameBlog::STATUS_ARCHIVED: + return pht( + '%s archived the blog %s.', + $this->renderAuthor(), + $this->renderObject()); + } + } + + public function getIcon() { + $new = $this->getNewValue(); + if ($new == PhameBlog::STATUS_ARCHIVED) { + return 'fa-ban'; + } else { + return 'fa-check'; + } + } + +} diff --git a/src/applications/phame/xaction/PhameBlogSubtitleTransaction.php b/src/applications/phame/xaction/PhameBlogSubtitleTransaction.php new file mode 100644 index 0000000000..87788a31f7 --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogSubtitleTransaction.php @@ -0,0 +1,63 @@ +getSubtitle(); + } + + public function applyInternalEffects($object, $value) { + $object->setSubtitle($value); + } + + public function getTitle() { + $old = $this->getOldValue(); + if ($old === null) { + return pht( + '%s set this blog\'s subtitle to "%s".', + $this->renderAuthor(), + $this->renderNewValue()); + } else { + return pht( + '%s updated the blog\'s subtitle to "%s".', + $this->renderAuthor(), + $this->renderNewValue()); + } + } + + public function getTitleForFeed() { + $old = $this->getOldValue(); + if ($old === null) { + return pht( + '%s set the subtitle for %s.', + $this->renderAuthor(), + $this->renderObject()); + } else { + return pht( + '%s updated the subtitle for %s.', + $this->renderAuthor(), + $this->renderObject()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + $max_length = $object->getColumnMaximumByteLength('subtitle'); + foreach ($xactions as $xaction) { + $new_value = $xaction->getNewValue(); + $new_length = strlen($new_value); + if ($new_length > $max_length) { + $errors[] = $this->newInvalidError( + pht('The subtitle can be no longer than %s characters.', + new PhutilNumber($max_length))); + } + } + + return $errors; + } + +} diff --git a/src/applications/phame/xaction/PhameBlogTransactionType.php b/src/applications/phame/xaction/PhameBlogTransactionType.php new file mode 100644 index 0000000000..cf83633b9f --- /dev/null +++ b/src/applications/phame/xaction/PhameBlogTransactionType.php @@ -0,0 +1,4 @@ +