1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 16:22:43 +01:00

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
This commit is contained in:
tuomaspelkonen 2011-03-30 19:21:09 -07:00
parent c795aaea29
commit 28fe9f4eca
15 changed files with 311 additions and 4 deletions

View file

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

View file

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

View file

@ -244,6 +244,9 @@ class AphrontDefaultApplicationConfiguration
=> 'HeraldTranscriptController',
),
'/preferences/' => array(
'$' => 'PhabricatorEditPreferencesController'
),
);
}

View file

@ -1199,7 +1199,7 @@ EOSYNTHETIC;
$table = null;
if ($contents) {
$table =
'<table class="differential-diff remarkup-code">'.
'<table class="differential-diff remarkup-code PhabricatorMonospaced">'.
$contents.
'</table>';
}

View file

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

View file

@ -0,0 +1,39 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorUserPreferences extends PhabricatorUserDAO {
const PREFERENCE_MONOSPACED = 'monospaced';
const PREFERENCE_TITLES = 'titles';
protected $userPHID;
protected $preferences;
public function getConfiguration() {
return array(
self::CONFIG_SERIALIZATION => array(
'preferences' => self::SERIALIZATION_JSON,
),
self::CONFIG_TIMESTAMPS => false,
) + parent::getConfiguration();
}
public function getPreference($key) {
return $this->getPreferences()[$key];
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/people/storage/base');
phutil_require_source('PhabricatorUserPreferences.php');

View file

@ -34,6 +34,8 @@ class PhabricatorUser extends PhabricatorUserDAO {
protected $conduitCertificate;
protected $preferences = null;
public function getProfileImagePHID() {
return nonempty(
$this->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;
}
}

View file

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

View file

@ -0,0 +1,34 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PhabricatorPreferencesController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->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());
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorPreferencesController.php');

View file

@ -0,0 +1,111 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorEditPreferencesController
extends PhabricatorPreferencesController {
public function processRequest() {
$request = $this->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 = <<<EXAMPLE
// This is what your monospaced font currently looks like.
function helloWorld() {
alert("Hello world!");
}
EXAMPLE;
$form = id(new AphrontFormView())
->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(
'<pre class="PhabricatorMonospaced">'.
phutil_escape_html($example_string).
'</pre>'))
->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',
));
}
}

View file

@ -0,0 +1,20 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/people/storage/preferences');
phutil_require_module('phabricator', 'applications/preferences/controller/base');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorEditPreferencesController.php');

View file

@ -60,7 +60,19 @@ class PhabricatorStandardPageView extends AphrontPageView {
}
public function getTitle() {
return $this->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 =
'<script type="text/javascript">'.
'(top != self) && top.location.replace(self.location.href);'.
'window.__DEV__=1;'.
@ -105,6 +117,27 @@ class PhabricatorStandardPageView extends AphrontPageView {
$response->renderResourcesOfType('css').
'<script type="text/javascript" src="/rsrc/js/javelin/init.dev.js">'.
'</script>';
$request = $this->getRequest();
if ($request) {
$user = $request->getUser();
if ($user) {
$monospaced = $user->loadPreferences()->getPreference(
PhabricatorUserPreferences::PREFERENCE_MONOSPACED
);
if (strlen($monospaced)) {
$head .=
'<style type="text/css">'.
'.PhabricatorMonospaced { font: '.
$monospaced.
' !important; }'.
'</style>';
}
}
}
return $head;
}
public function setGlyph($glyph) {

View file

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