From 28fe9f4eca8c65c91e79379c601f18d71c58a3ac Mon Sep 17 00:00:00 2001 From: tuomaspelkonen Date: Wed, 30 Mar 2011 19:21:09 -0700 Subject: [PATCH] User preferences ported from tools Summary: Internal tools, e.g., differential and diffusion have user defined preferences for monospaced font and the option for showing either the name of the tool or the glyph of the tool in the title. These preferences were ported to phabricator. These preferences can be modified in /preferences/ and they both affect diffusion and differential at the moment. Test Plan: * Created an empty database * Loaded /preferences/ and modified the monospaced font and clicked save * Confirmed that the same page was loaded with the message that preferences have been saved and that the example text used the user defined font * in /preferences/ changed the option to show tool names as plain text and clicked save * Confirmed that the same page was loaded with '[Preferences]' in the title instead of a glyph * These same tests were also executed for differential and diffusion Reviewers: epriestley CC: jungejason Differential Revision: 91 --- resources/sql/patches/015.preferences.sql | 6 + src/__phutil_library_map__.php | 6 + ...AphrontDefaultApplicationConfiguration.php | 3 + .../changeset/DifferentialChangesetParser.php | 2 +- .../file/DiffusionBrowseFileController.php | 2 +- .../PhabricatorUserPreferences.php | 39 ++++++ .../people/storage/preferences/__init__.php | 12 ++ .../people/storage/user/PhabricatorUser.php | 26 ++++ .../people/storage/user/__init__.php | 1 + .../base/PhabricatorPreferencesController.php | 34 ++++++ .../preferences/controller/base/__init__.php | 15 +++ .../PhabricatorEditPreferencesController.php | 111 ++++++++++++++++++ .../preferences/controller/edit/__init__.php | 20 ++++ .../standard/PhabricatorStandardPageView.php | 37 +++++- src/view/page/standard/__init__.php | 1 + 15 files changed, 311 insertions(+), 4 deletions(-) create mode 100644 resources/sql/patches/015.preferences.sql create mode 100644 src/applications/people/storage/preferences/PhabricatorUserPreferences.php create mode 100644 src/applications/people/storage/preferences/__init__.php create mode 100644 src/applications/preferences/controller/base/PhabricatorPreferencesController.php create mode 100644 src/applications/preferences/controller/base/__init__.php create mode 100644 src/applications/preferences/controller/edit/PhabricatorEditPreferencesController.php create mode 100644 src/applications/preferences/controller/edit/__init__.php diff --git a/resources/sql/patches/015.preferences.sql b/resources/sql/patches/015.preferences.sql new file mode 100644 index 0000000000..08a6c71d8a --- /dev/null +++ b/resources/sql/patches/015.preferences.sql @@ -0,0 +1,6 @@ +CREATE TABLE phabricator_user.user_preferences ( + id int unsigned not null auto_increment primary key, + userPHID varchar(64) binary not null, + preferences longblob not null, + unique key (userPHID) +); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 49289e0c21..7e96b82ef7 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -270,6 +270,7 @@ phutil_register_library_map(array( 'PhabricatorDirectoryMainController' => 'applications/directory/controller/main', 'PhabricatorDraft' => 'applications/draft/storage/draft', 'PhabricatorDraftDAO' => 'applications/draft/storage/base', + 'PhabricatorEditPreferencesController' => 'applications/preferences/controller/edit', 'PhabricatorEmailLoginController' => 'applications/auth/controller/email', 'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken', 'PhabricatorEnv' => 'infrastructure/env', @@ -326,6 +327,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleListController' => 'applications/people/controller/list', 'PhabricatorPeopleProfileController' => 'applications/people/controller/profile', 'PhabricatorPeopleProfileEditController' => 'applications/people/controller/profileedit', + 'PhabricatorPreferencesController' => 'applications/preferences/controller/base', 'PhabricatorProject' => 'applications/project/storage/project', 'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation', 'PhabricatorProjectAffiliationEditController' => 'applications/project/controller/editaffiliation', @@ -389,6 +391,7 @@ phutil_register_library_map(array( 'PhabricatorUser' => 'applications/people/storage/user', 'PhabricatorUserDAO' => 'applications/people/storage/base', 'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo', + 'PhabricatorUserPreferences' => 'applications/people/storage/preferences', 'PhabricatorUserProfile' => 'applications/people/storage/profile', 'PhabricatorUserSettingsController' => 'applications/people/controller/settings', 'PhabricatorWorker' => 'infrastructure/daemon/workers/worker', @@ -615,6 +618,7 @@ phutil_register_library_map(array( 'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController', 'PhabricatorDraft' => 'PhabricatorDraftDAO', 'PhabricatorDraftDAO' => 'PhabricatorLiskDAO', + 'PhabricatorEditPreferencesController' => 'PhabricatorPreferencesController', 'PhabricatorEmailLoginController' => 'PhabricatorAuthController', 'PhabricatorEmailTokenController' => 'PhabricatorAuthController', 'PhabricatorFile' => 'PhabricatorFileDAO', @@ -662,6 +666,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleListController' => 'PhabricatorPeopleController', 'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController', 'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleController', + 'PhabricatorPreferencesController' => 'PhabricatorController', 'PhabricatorProject' => 'PhabricatorProjectDAO', 'PhabricatorProjectAffiliation' => 'PhabricatorProjectDAO', 'PhabricatorProjectAffiliationEditController' => 'PhabricatorProjectController', @@ -718,6 +723,7 @@ phutil_register_library_map(array( 'PhabricatorUser' => 'PhabricatorUserDAO', 'PhabricatorUserDAO' => 'PhabricatorLiskDAO', 'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO', + 'PhabricatorUserPreferences' => 'PhabricatorUserDAO', 'PhabricatorUserProfile' => 'PhabricatorUserDAO', 'PhabricatorUserSettingsController' => 'PhabricatorPeopleController', 'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO', diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index 0ddfdcf971..aed566c439 100755 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -244,6 +244,9 @@ class AphrontDefaultApplicationConfiguration => 'HeraldTranscriptController', ), + '/preferences/' => array( + '$' => 'PhabricatorEditPreferencesController' + ), ); } diff --git a/src/applications/differential/parser/changeset/DifferentialChangesetParser.php b/src/applications/differential/parser/changeset/DifferentialChangesetParser.php index 58ba4810e4..121347568f 100644 --- a/src/applications/differential/parser/changeset/DifferentialChangesetParser.php +++ b/src/applications/differential/parser/changeset/DifferentialChangesetParser.php @@ -1199,7 +1199,7 @@ EOSYNTHETIC; $table = null; if ($contents) { $table = - ''. + '
'. $contents. '
'; } diff --git a/src/applications/diffusion/controller/file/DiffusionBrowseFileController.php b/src/applications/diffusion/controller/file/DiffusionBrowseFileController.php index b7f4a161cd..a6f5ca6322 100644 --- a/src/applications/diffusion/controller/file/DiffusionBrowseFileController.php +++ b/src/applications/diffusion/controller/file/DiffusionBrowseFileController.php @@ -142,7 +142,7 @@ class DiffusionBrowseFileController extends DiffusionController { $corpus_table = phutil_render_tag( 'table', array( - 'class' => "diffusion-source remarkup-code", + 'class' => "diffusion-source remarkup-code PhabricatorMonospaced", ), implode("\n", $rows)); $corpus = phutil_render_tag( diff --git a/src/applications/people/storage/preferences/PhabricatorUserPreferences.php b/src/applications/people/storage/preferences/PhabricatorUserPreferences.php new file mode 100644 index 0000000000..42438a3ada --- /dev/null +++ b/src/applications/people/storage/preferences/PhabricatorUserPreferences.php @@ -0,0 +1,39 @@ + array( + 'preferences' => self::SERIALIZATION_JSON, + ), + self::CONFIG_TIMESTAMPS => false, + ) + parent::getConfiguration(); + } + + public function getPreference($key) { + return $this->getPreferences()[$key]; + } +} diff --git a/src/applications/people/storage/preferences/__init__.php b/src/applications/people/storage/preferences/__init__.php new file mode 100644 index 0000000000..642ad05c2c --- /dev/null +++ b/src/applications/people/storage/preferences/__init__.php @@ -0,0 +1,12 @@ +profileImagePHID, @@ -161,4 +163,28 @@ class PhabricatorUser extends PhabricatorUserDAO { return false; } + public function loadPreferences() { + if ($this->preferences) { + return $this->preferences; + } + + $preferences = id(new PhabricatorUserPreferences())->loadOneWhere( + 'userPHID = %s', + $this->getPHID()); + + if (!$preferences) { + $preferences = new PhabricatorUserPreferences(); + $preferences->setUserPHID($this->getPHID()); + + $default_dict = array( + PhabricatorUserPreferences::PREFERENCE_TITLES => 'glyph', + PhabricatorUserPreferences::PREFERENCE_MONOSPACED => ''); + + $preferences->setPreferences($default_dict); + } + + $this->preferences = $preferences; + return $preferences; + } + } diff --git a/src/applications/people/storage/user/__init__.php b/src/applications/people/storage/user/__init__.php index efe13374b1..8a7b435549 100644 --- a/src/applications/people/storage/user/__init__.php +++ b/src/applications/people/storage/user/__init__.php @@ -7,6 +7,7 @@ phutil_require_module('phabricator', 'applications/people/storage/base'); +phutil_require_module('phabricator', 'applications/people/storage/preferences'); phutil_require_module('phabricator', 'applications/phid/constants'); phutil_require_module('phabricator', 'applications/phid/storage/phid'); phutil_require_module('phabricator', 'infrastructure/env'); diff --git a/src/applications/preferences/controller/base/PhabricatorPreferencesController.php b/src/applications/preferences/controller/base/PhabricatorPreferencesController.php new file mode 100644 index 0000000000..af203647d1 --- /dev/null +++ b/src/applications/preferences/controller/base/PhabricatorPreferencesController.php @@ -0,0 +1,34 @@ +buildStandardPageView(); + + $page->setApplicationName('Preferences'); + $page->setBaseURI('/preferences/'); + $page->setTitle(idx($data, 'title')); + $page->setGlyph("\xE2\x9A\x92"); + $page->appendChild($view); + + $response = new AphrontWebpageResponse(); + return $response->setContent($page->render()); + } +} diff --git a/src/applications/preferences/controller/base/__init__.php b/src/applications/preferences/controller/base/__init__.php new file mode 100644 index 0000000000..6b30c6011c --- /dev/null +++ b/src/applications/preferences/controller/base/__init__.php @@ -0,0 +1,15 @@ +getRequest(); + $user = $request->getUser(); + $preferences = $user->loadPreferences(); + + if ($request->isFormPost()) { + $monospaced = $request->getStr( + PhabricatorUserPreferences::PREFERENCE_MONOSPACED); + + // Prevent the user from doing stupid things. + $monospaced = preg_replace('/[^a-z0-9 ,"]+/i', '', $monospaced); + + $pref_dict = array( + PhabricatorUserPreferences::PREFERENCE_TITLES => + $request->getStr(PhabricatorUserPreferences::PREFERENCE_TITLES), + PhabricatorUserPreferences::PREFERENCE_MONOSPACED => + $monospaced); + + $preferences->setPreferences($pref_dict); + $preferences->save(); + return id(new AphrontRedirectResponse()) + ->setURI('/preferences/?saved=true'); + } + + $example_string = <<setAction('/preferences/') + ->setUser($user) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel('Page Titles') + ->setName(PhabricatorUserPreferences::PREFERENCE_TITLES) + ->setValue($preferences->getPreference( + PhabricatorUserPreferences::PREFERENCE_TITLES)) + ->setOptions( + array( + 'glyph' => + "In page titles, show Tool names as unicode glyphs: \xE2\x9A\x99", + 'text' => + 'In page titles, show Tool names as plain text: [Differential]', + ))) + ->appendChild( + id(new AphrontFormTextControl()) + ->setLabel('Monospaced Font') + ->setName(PhabricatorUserPreferences::PREFERENCE_MONOSPACED) + ->setCaption( + 'Overrides default fonts in tools like Differential. '. + '(Default: 10px "Menlo", "Consolas", "Monaco", '. + 'monospace)') + ->setValue($preferences->getPreference( + PhabricatorUserPreferences::PREFERENCE_MONOSPACED))) + ->appendChild( + id(new AphrontFormMarkupControl()) + ->setValue( + '
'.
+          phutil_escape_html($example_string).
+          '
')) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Save Preferences')); + + $panel = new AphrontPanelView(); + $panel->appendChild($form); + + $error_view = null; + if ($request->getStr('saved') === 'true') { + $error_view = id(new AphrontErrorView()) + ->setTitle('Preferences Saved') + ->setSeverity(AphrontErrorView::SEVERITY_NOTICE) + ->setErrors(array('Your preferences have been saved.')); + } + + return $this->buildStandardPageResponse( + array( + $error_view, + $panel, + ), + array( + 'title' => 'Edit Preferences', + )); + + } +} + diff --git a/src/applications/preferences/controller/edit/__init__.php b/src/applications/preferences/controller/edit/__init__.php new file mode 100644 index 0000000000..d91533583a --- /dev/null +++ b/src/applications/preferences/controller/edit/__init__.php @@ -0,0 +1,20 @@ +getGlyph().' '.parent::getTitle(); + $use_glyph = true; + $request = $this->getRequest(); + if ($request) { + $user = $request->getUser(); + if ($user && $user->loadPreferences()->getPreference( + PhabricatorUserPreferences::PREFERENCE_TITLES) !== 'glyph') { + $use_glyph = false; + } + } + + return ($use_glyph ? + $this->getGlyph() : '['.$this->getApplicationName().']'). + ' '.parent::getTitle(); } @@ -97,7 +109,7 @@ class PhabricatorStandardPageView extends AphrontPageView { protected function getHead() { $response = CelerityAPI::getStaticResourceResponse(); - return + $head = ''; + + $request = $this->getRequest(); + if ($request) { + $user = $request->getUser(); + if ($user) { + $monospaced = $user->loadPreferences()->getPreference( + PhabricatorUserPreferences::PREFERENCE_MONOSPACED + ); + + if (strlen($monospaced)) { + $head .= + ''; + } + } + } + + return $head; } public function setGlyph($glyph) { diff --git a/src/view/page/standard/__init__.php b/src/view/page/standard/__init__.php index 5b4e699da5..7db98f4535 100644 --- a/src/view/page/standard/__init__.php +++ b/src/view/page/standard/__init__.php @@ -6,6 +6,7 @@ +phutil_require_module('phabricator', 'applications/people/storage/preferences'); phutil_require_module('phabricator', 'infrastructure/celerity/api'); phutil_require_module('phabricator', 'infrastructure/env'); phutil_require_module('phabricator', 'infrastructure/javelin/api');