From b92fe7dbdacccce8a20e7e5353b857e385fb00a8 Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 10 Jul 2013 05:09:59 -0700 Subject: [PATCH] Merge profile "About" into main profile and simplify some custom field stuff Summary: Ref T1703. Drive "user since" with a custom field and make the other fields render into a property list. Users can make their profiles a little more personal/obnoxious now. Also delete a bunch of code. Test Plan: {F49415} Reviewers: chad, btrahan Reviewed By: chad CC: aran Maniphest Tasks: T1703 Differential Revision: https://secure.phabricator.com/D6401 --- src/__phutil_library_map__.php | 2 + .../config/PhabricatorUserConfigOptions.php | 1 + .../PhabricatorPeopleProfileController.php | 85 ++++--------------- ...PhabricatorPeopleProfileEditController.php | 2 +- .../customfield/PhabricatorUserBlurbField.php | 29 ++++++- .../PhabricatorUserCustomField.php | 24 ------ .../PhabricatorUserCustomFieldInterface.php | 3 - .../PhabricatorUserRealNameField.php | 12 +++ .../customfield/PhabricatorUserSinceField.php | 30 +++++++ .../customfield/PhabricatorUserTitleField.php | 12 +++ .../field/PhabricatorCustomField.php | 69 ++++++++++++++- .../markup/PhabricatorMarkupEngine.php | 9 -- .../layout/PhabricatorPropertyListView.php | 25 ++++++ 13 files changed, 197 insertions(+), 106 deletions(-) create mode 100644 src/applications/people/customfield/PhabricatorUserSinceField.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 7ef1e0236c..ecf2b65032 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1616,6 +1616,7 @@ phutil_register_library_map(array( 'PhabricatorUserRealNameField' => 'applications/people/customfield/PhabricatorUserRealNameField.php', 'PhabricatorUserSSHKey' => 'applications/settings/storage/PhabricatorUserSSHKey.php', 'PhabricatorUserSearchIndexer' => 'applications/people/search/PhabricatorUserSearchIndexer.php', + 'PhabricatorUserSinceField' => 'applications/people/customfield/PhabricatorUserSinceField.php', 'PhabricatorUserStatus' => 'applications/people/storage/PhabricatorUserStatus.php', 'PhabricatorUserStatusInvalidEpochException' => 'applications/people/exception/PhabricatorUserStatusInvalidEpochException.php', 'PhabricatorUserStatusOverlapException' => 'applications/people/exception/PhabricatorUserStatusOverlapException.php', @@ -3568,6 +3569,7 @@ phutil_register_library_map(array( 'PhabricatorUserRealNameField' => 'PhabricatorUserCustomField', 'PhabricatorUserSSHKey' => 'PhabricatorUserDAO', 'PhabricatorUserSearchIndexer' => 'PhabricatorSearchDocumentIndexer', + 'PhabricatorUserSinceField' => 'PhabricatorUserCustomField', 'PhabricatorUserStatus' => 'PhabricatorUserDAO', 'PhabricatorUserStatusInvalidEpochException' => 'Exception', 'PhabricatorUserStatusOverlapException' => 'Exception', diff --git a/src/applications/people/config/PhabricatorUserConfigOptions.php b/src/applications/people/config/PhabricatorUserConfigOptions.php index f5336ca1ad..53a40c341e 100644 --- a/src/applications/people/config/PhabricatorUserConfigOptions.php +++ b/src/applications/people/config/PhabricatorUserConfigOptions.php @@ -16,6 +16,7 @@ final class PhabricatorUserConfigOptions $default = array( id(new PhabricatorUserRealNameField())->getFieldKey() => true, id(new PhabricatorUserTitleField())->getFieldKey() => true, + id(new PhabricatorUserSinceField())->getFieldKey() => true, id(new PhabricatorUserBlurbField())->getFieldKey() => true, ); diff --git a/src/applications/people/controller/PhabricatorPeopleProfileController.php b/src/applications/people/controller/PhabricatorPeopleProfileController.php index 0b1f33314d..58a352d21a 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileController.php @@ -5,7 +5,6 @@ final class PhabricatorPeopleProfileController private $username; private $page; - private $profileUser; public function shouldRequireAdmin() { // Default for people app is true @@ -18,10 +17,6 @@ final class PhabricatorPeopleProfileController $this->page = idx($data, 'page'); } - public function getProfileUser() { - return $this->profileUser; - } - private function getMainFilters($username) { return array( array( @@ -29,11 +24,6 @@ final class PhabricatorPeopleProfileController 'name' => pht('Feed'), 'href' => '/p/'.$username.'/feed/' ), - array( - 'key' => 'about', - 'name' => pht('About'), - 'href' => '/p/'.$username.'/about/' - ) ); } @@ -48,8 +38,6 @@ final class PhabricatorPeopleProfileController return new Aphront404Response(); } - $this->profileUser = $user; - require_celerity_resource('phabricator-profile-css'); $profile = $user->loadUserProfile(); @@ -76,16 +64,7 @@ final class PhabricatorPeopleProfileController $this->page = $nav->selectFilter($this->page, 'feed'); - switch ($this->page) { - case 'feed': - $content = $this->renderUserFeed($user); - break; - case 'about': - $content = $this->renderBasicInformation($user, $profile); - break; - default: - throw new Exception("Unknown page '{$this->page}'!"); - } + $content = $this->renderUserFeed($user); $picture = $user->loadProfileImageURI(); @@ -133,8 +112,11 @@ final class PhabricatorPeopleProfileController ->setHref($this->getApplicationURI('edit/'.$user->getID().'/'))); } + $properties = $this->buildPropertyView($user); + $nav->appendChild($header); $nav->appendChild($actions); + $nav->appendChild($properties); $nav->appendChild($content); return $this->buildApplicationPage( @@ -146,55 +128,24 @@ final class PhabricatorPeopleProfileController )); } - private function renderBasicInformation($user, $profile) { - - $blurb = nonempty( - $profile->getBlurb(), - '//'.pht('Nothing is known about this rare specimen.').'//'); - + private function buildPropertyView(PhabricatorUser $user) { $viewer = $this->getRequest()->getUser(); - $engine = PhabricatorMarkupEngine::newProfileMarkupEngine(); - $engine->setConfig('viewer', $viewer); - $blurb = $engine->markupText($blurb); + $view = id(new PhabricatorPropertyListView()) + ->setUser($viewer) + ->setObject($user); - $content = hsprintf( - '
-

%s

-
- - - - - - - - - -
%s%s
%s%s
-
-
'. - '
-

%s

-
- - - - - -
%s%s
-
-
', - pht('Basic Information'), - pht('PHID'), - $user->getPHID(), - pht('User Since'), - phabricator_datetime($user->getDateCreated(), $viewer), - pht('Flavor Text'), - pht('Blurb'), - $blurb); + $fields = PhabricatorCustomField::getObjectFields( + $user, + PhabricatorCustomField::ROLE_VIEW); - return $content; + foreach ($fields as $field) { + $field->setViewer($viewer); + } + + $view->applyCustomFields($fields); + + return $view; } private function renderUserFeed(PhabricatorUser $user) { diff --git a/src/applications/people/controller/PhabricatorPeopleProfileEditController.php b/src/applications/people/controller/PhabricatorPeopleProfileEditController.php index c1d041a76d..ea16e4b873 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileEditController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileEditController.php @@ -34,7 +34,7 @@ final class PhabricatorPeopleProfileEditController $fields = PhabricatorCustomField::getObjectFields( $user, - PhabricatorUserCustomFieldInterface::ROLE_EDIT); + PhabricatorCustomField::ROLE_EDIT); if ($request->isFormPost()) { $xactions = array(); diff --git a/src/applications/people/customfield/PhabricatorUserBlurbField.php b/src/applications/people/customfield/PhabricatorUserBlurbField.php index 4857502653..1db87990da 100644 --- a/src/applications/people/customfield/PhabricatorUserBlurbField.php +++ b/src/applications/people/customfield/PhabricatorUserBlurbField.php @@ -17,7 +17,15 @@ final class PhabricatorUserBlurbField return pht('Short blurb about the user.'); } - public function canDisableField() { + public function shouldAppearInApplicationTransactions() { + return true; + } + + public function shouldAppearInEditView() { + return true; + } + + public function shouldAppearInPropertyView() { return true; } @@ -49,4 +57,23 @@ final class PhabricatorUserBlurbField ->setLabel($this->getFieldName()); } + public function renderPropertyViewLabel() { + return null; + } + + public function renderPropertyViewValue() { + $blurb = $this->getObject()->loadUserProfile()->getBlurb(); + if (!strlen($blurb)) { + return null; + } + return PhabricatorMarkupEngine::renderOneObject( + id(new PhabricatorMarkupOneOff())->setContent($blurb), + 'default', + $this->getViewer()); + } + + public function getStyleForPropertyView() { + return 'block'; + } + } diff --git a/src/applications/people/customfield/PhabricatorUserCustomField.php b/src/applications/people/customfield/PhabricatorUserCustomField.php index d8ebfdccd8..afcea5dcae 100644 --- a/src/applications/people/customfield/PhabricatorUserCustomField.php +++ b/src/applications/people/customfield/PhabricatorUserCustomField.php @@ -5,28 +5,4 @@ abstract class PhabricatorUserCustomField implements PhabricatorUserCustomFieldInterface { - public function shouldEnableForRole($role) { - switch ($role) { - case PhabricatorUserCustomFieldInterface::ROLE_EDIT: - return $this->shouldAppearOnProfileEdit(); - } - return parent::shouldEnableForRole($role); - } - - public function shouldAppearOnProfileEdit() { - return true; - } - - -/* -( PhabricatorCustomField )--------------------------------------------- */ - - - public function canDisableField() { - return false; - } - - public function shouldAppearInApplicationTransactions() { - return true; - } - } diff --git a/src/applications/people/customfield/PhabricatorUserCustomFieldInterface.php b/src/applications/people/customfield/PhabricatorUserCustomFieldInterface.php index ba065cac00..7456ee631e 100644 --- a/src/applications/people/customfield/PhabricatorUserCustomFieldInterface.php +++ b/src/applications/people/customfield/PhabricatorUserCustomFieldInterface.php @@ -2,8 +2,5 @@ interface PhabricatorUserCustomFieldInterface { - const ROLE_EDIT = 'user.edit'; - - public function shouldAppearOnProfileEdit(); } diff --git a/src/applications/people/customfield/PhabricatorUserRealNameField.php b/src/applications/people/customfield/PhabricatorUserRealNameField.php index d19eb0f7ee..64f748242d 100644 --- a/src/applications/people/customfield/PhabricatorUserRealNameField.php +++ b/src/applications/people/customfield/PhabricatorUserRealNameField.php @@ -17,6 +17,18 @@ final class PhabricatorUserRealNameField return pht('Stores the real name of the user, like "Abraham Lincoln".'); } + public function canDisableField() { + return false; + } + + public function shouldAppearInApplicationTransactions() { + return true; + } + + public function shouldAppearInEditView() { + return true; + } + protected function didSetObject(PhabricatorCustomFieldInterface $object) { $this->value = $object->getRealName(); } diff --git a/src/applications/people/customfield/PhabricatorUserSinceField.php b/src/applications/people/customfield/PhabricatorUserSinceField.php new file mode 100644 index 0000000000..1feaf61eb4 --- /dev/null +++ b/src/applications/people/customfield/PhabricatorUserSinceField.php @@ -0,0 +1,30 @@ +getObject()->getDateCreated(), + $this->getViewer()); + } + +} diff --git a/src/applications/people/customfield/PhabricatorUserTitleField.php b/src/applications/people/customfield/PhabricatorUserTitleField.php index 5e9fe2c65e..933c3fda10 100644 --- a/src/applications/people/customfield/PhabricatorUserTitleField.php +++ b/src/applications/people/customfield/PhabricatorUserTitleField.php @@ -17,6 +17,18 @@ final class PhabricatorUserTitleField return pht('User title, like "CEO" or "Assistant to the Manager".'); } + public function canDisableField() { + return false; + } + + public function shouldAppearInApplicationTransactions() { + return true; + } + + public function shouldAppearInEditView() { + return true; + } + protected function didSetObject(PhabricatorCustomFieldInterface $object) { $this->value = $object->loadUserProfile()->getTitle(); } diff --git a/src/infrastructure/customfield/field/PhabricatorCustomField.php b/src/infrastructure/customfield/field/PhabricatorCustomField.php index f904bc5209..24f3136413 100644 --- a/src/infrastructure/customfield/field/PhabricatorCustomField.php +++ b/src/infrastructure/customfield/field/PhabricatorCustomField.php @@ -7,6 +7,9 @@ * @task storage Field Storage * @task appsearch Integration with ApplicationSearch * @task appxaction Integration with ApplicationTransactions + * @task edit Integration with edit views + * @task view Integration with property views + * @task list Integration with list views */ abstract class PhabricatorCustomField { @@ -17,6 +20,9 @@ abstract class PhabricatorCustomField { const ROLE_APPLICATIONSEARCH = 'ApplicationSearch'; const ROLE_STORAGE = 'storage'; const ROLE_DEFAULT = 'default'; + const ROLE_EDIT = 'edit'; + const ROLE_VIEW = 'view'; + const ROLE_LIST = 'list'; /* -( Building Applications with Custom Fields )--------------------------- */ @@ -219,6 +225,12 @@ abstract class PhabricatorCustomField { return $this->shouldAppearInApplicationSearch(); case self::ROLE_STORAGE: return ($this->getStorageKey() !== null); + case self::ROLE_EDIT: + return $this->shouldAppearInEditView(); + case self::ROLE_VIEW: + return $this->shouldAppearInPropertyView(); + case self::ROLE_LIST: + return $this->shouldAppearInListView(); case self::ROLE_DEFAULT: return true; default: @@ -605,7 +617,7 @@ abstract class PhabricatorCustomField { /** * @task edit */ - public function shouldAppearOnEditView() { + public function shouldAppearInEditView() { return false; } @@ -626,4 +638,59 @@ abstract class PhabricatorCustomField { } +/* -( Property View )------------------------------------------------------ */ + + + /** + * @task view + */ + public function shouldAppearInPropertyView() { + return false; + } + + + /** + * @task view + */ + public function renderPropertyViewLabel() { + return $this->getFieldName(); + } + + + /** + * @task view + */ + public function renderPropertyViewValue() { + throw new PhabricatorCustomFieldImplementationIncompleteException($this); + } + + + /** + * @task view + */ + public function getStyleForPropertyView() { + return 'property'; + } + + +/* -( List View )---------------------------------------------------------- */ + + + /** + * @task list + */ + public function shouldAppearInListView() { + return false; + } + + + /** + * @task list + */ + public function renderOnListItem(PhabricatorObjectItemView $view) { + throw new PhabricatorCustomFieldImplementationIncompleteException($this); + } + + + } diff --git a/src/infrastructure/markup/PhabricatorMarkupEngine.php b/src/infrastructure/markup/PhabricatorMarkupEngine.php index 7702660f9b..ee407a68c8 100644 --- a/src/infrastructure/markup/PhabricatorMarkupEngine.php +++ b/src/infrastructure/markup/PhabricatorMarkupEngine.php @@ -346,15 +346,6 @@ final class PhabricatorMarkupEngine { } - /** - * @task engine - */ - public static function newProfileMarkupEngine() { - return self::newMarkupEngine(array( - )); - } - - /** * @task engine */ diff --git a/src/view/layout/PhabricatorPropertyListView.php b/src/view/layout/PhabricatorPropertyListView.php index c5a53bf52b..137618b8e2 100644 --- a/src/view/layout/PhabricatorPropertyListView.php +++ b/src/view/layout/PhabricatorPropertyListView.php @@ -81,7 +81,32 @@ final class PhabricatorPropertyListView extends AphrontView { $this->invokedWillRenderEvent = true; } + public function applyCustomFields(array $fields) { + assert_instances_of($fields, 'PhabricatorCustomField'); + foreach ($fields as $field) { + $label = $field->renderPropertyViewLabel(); + $value = $field->renderPropertyViewValue(); + if ($value !== null) { + switch ($field->getStyleForPropertyView()) { + case 'property': + $this->addProperty($label, $value); + break; + case 'block': + $this->invokeWillRenderEvent(); + if ($label !== null) { + $this->addSectionHeader($label); + } + $this->addTextContent($value); + break; + default: + throw new Exception( + "Unknown field property view style; valid styles are ". + "'block' and 'property'."); + } + } + } + } public function render() { $this->invokeWillRenderEvent();