Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / settings / panel / PhabricatorSettingsPanel.php
blobe2efd920931f37a8d9576073d7cb5733ea63fd13
1 <?php
3 /**
4 * Defines a settings panel. Settings panels appear in the Settings application,
5 * and behave like lightweight controllers -- generally, they render some sort
6 * of form with options in it, and then update preferences when the user
7 * submits the form. By extending this class, you can add new settings
8 * panels.
10 * @task config Panel Configuration
11 * @task panel Panel Implementation
12 * @task internal Internals
14 abstract class PhabricatorSettingsPanel extends Phobject {
16 private $user;
17 private $viewer;
18 private $controller;
19 private $navigation;
20 private $overrideURI;
21 private $preferences;
23 public function setUser(PhabricatorUser $user) {
24 $this->user = $user;
25 return $this;
28 public function getUser() {
29 return $this->user;
32 public function setViewer(PhabricatorUser $viewer) {
33 $this->viewer = $viewer;
34 return $this;
37 public function getViewer() {
38 return $this->viewer;
41 public function setOverrideURI($override_uri) {
42 $this->overrideURI = $override_uri;
43 return $this;
46 final public function setController(PhabricatorController $controller) {
47 $this->controller = $controller;
48 return $this;
51 final public function getController() {
52 return $this->controller;
55 final public function setNavigation(AphrontSideNavFilterView $navigation) {
56 $this->navigation = $navigation;
57 return $this;
60 final public function getNavigation() {
61 return $this->navigation;
64 public function setPreferences(PhabricatorUserPreferences $preferences) {
65 $this->preferences = $preferences;
66 return $this;
69 public function getPreferences() {
70 return $this->preferences;
73 final public static function getAllPanels() {
74 $panels = id(new PhutilClassMapQuery())
75 ->setAncestorClass(__CLASS__)
76 ->setUniqueMethod('getPanelKey')
77 ->execute();
78 return msortv($panels, 'getPanelOrderVector');
81 final public static function getAllDisplayPanels() {
82 $panels = array();
83 $groups = PhabricatorSettingsPanelGroup::getAllPanelGroupsWithPanels();
84 foreach ($groups as $group) {
85 foreach ($group->getPanels() as $key => $panel) {
86 $panels[$key] = $panel;
90 return $panels;
93 final public function getPanelGroup() {
94 $group_key = $this->getPanelGroupKey();
96 $groups = PhabricatorSettingsPanelGroup::getAllPanelGroupsWithPanels();
97 $group = idx($groups, $group_key);
98 if (!$group) {
99 throw new Exception(
100 pht(
101 'No settings panel group with key "%s" exists!',
102 $group_key));
105 return $group;
109 /* -( Panel Configuration )------------------------------------------------ */
113 * Return a unique string used in the URI to identify this panel, like
114 * "example".
116 * @return string Unique panel identifier (used in URIs).
117 * @task config
119 public function getPanelKey() {
120 return $this->getPhobjectClassConstant('PANELKEY');
125 * Return a human-readable description of the panel's contents, like
126 * "Example Settings".
128 * @return string Human-readable panel name.
129 * @task config
131 abstract public function getPanelName();
135 * Return an icon for the panel in the menu.
137 * @return string Icon identifier.
138 * @task config
140 public function getPanelMenuIcon() {
141 return 'fa-wrench';
145 * Return a panel group key constant for this panel.
147 * @return const Panel group key.
148 * @task config
150 abstract public function getPanelGroupKey();
154 * Return false to prevent this panel from being displayed or used. You can
155 * do, e.g., configuration checks here, to determine if the feature your
156 * panel controls is unavailable in this install. By default, all panels are
157 * enabled.
159 * @return bool True if the panel should be shown.
160 * @task config
162 public function isEnabled() {
163 return true;
168 * Return true if this panel is available to users while editing their own
169 * settings.
171 * @return bool True to enable management on behalf of a user.
172 * @task config
174 public function isUserPanel() {
175 return true;
180 * Return true if this panel is available to administrators while managing
181 * bot and mailing list accounts.
183 * @return bool True to enable management on behalf of accounts.
184 * @task config
186 public function isManagementPanel() {
187 return false;
192 * Return true if this panel is available while editing settings templates.
194 * @return bool True to allow editing in templates.
195 * @task config
197 public function isTemplatePanel() {
198 return false;
202 * Return true if this panel should be available when enrolling in MFA on
203 * a new account with MFA requiredd.
205 * @return bool True to allow configuration during MFA enrollment.
206 * @task config
208 public function isMultiFactorEnrollmentPanel() {
209 return false;
213 /* -( Panel Implementation )----------------------------------------------- */
217 * Process a user request for this settings panel. Implement this method like
218 * a lightweight controller. If you return an @{class:AphrontResponse}, the
219 * response will be used in whole. If you return anything else, it will be
220 * treated as a view and composed into a normal settings page.
222 * Generally, render your settings panel by returning a form, then return
223 * a redirect when the user saves settings.
225 * @param AphrontRequest Incoming request.
226 * @return wild Response to request, either as an
227 * @{class:AphrontResponse} or something which can
228 * be composed into a @{class:AphrontView}.
229 * @task panel
231 abstract public function processRequest(AphrontRequest $request);
235 * Get the URI for this panel.
237 * @param string? Optional path to append.
238 * @return string Relative URI for the panel.
239 * @task panel
241 final public function getPanelURI($path = '') {
242 $path = ltrim($path, '/');
244 if ($this->overrideURI) {
245 return rtrim($this->overrideURI, '/').'/'.$path;
248 $key = $this->getPanelKey();
249 $key = phutil_escape_uri($key);
251 $user = $this->getUser();
252 if ($user) {
253 if ($user->isLoggedIn()) {
254 $username = $user->getUsername();
255 return "/settings/user/{$username}/page/{$key}/{$path}";
256 } else {
257 // For logged-out users, we can't put their username in the URI. This
258 // page will prompt them to login, then redirect them to the correct
259 // location.
260 return "/settings/panel/{$key}/";
262 } else {
263 $builtin = $this->getPreferences()->getBuiltinKey();
264 return "/settings/builtin/{$builtin}/page/{$key}/{$path}";
269 /* -( Internals )---------------------------------------------------------- */
273 * Generates a key to sort the list of panels.
275 * @return string Sortable key.
276 * @task internal
278 final public function getPanelOrderVector() {
279 return id(new PhutilSortVector())
280 ->addString($this->getPanelName());
283 protected function newDialog() {
284 return $this->getController()->newDialog();
287 protected function writeSetting(
288 PhabricatorUserPreferences $preferences,
289 $key,
290 $value) {
291 $viewer = $this->getViewer();
292 $request = $this->getController()->getRequest();
294 $editor = id(new PhabricatorUserPreferencesEditor())
295 ->setActor($viewer)
296 ->setContentSourceFromRequest($request)
297 ->setContinueOnNoEffect(true)
298 ->setContinueOnMissingFields(true);
300 $xactions = array();
301 $xactions[] = $preferences->newTransaction($key, $value);
302 $editor->applyTransactions($preferences, $xactions);
306 public function newBox($title, $content, $actions = array()) {
307 $header = id(new PHUIHeaderView())
308 ->setHeader($title);
310 foreach ($actions as $action) {
311 $header->addActionLink($action);
314 $view = id(new PHUIObjectBoxView())
315 ->setHeader($header)
316 ->appendChild($content)
317 ->setBackground(PHUIObjectBoxView::WHITE_CONFIG);
319 return $view;