PreferencesFormOOUI.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. /**
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. * http://www.gnu.org/copyleft/gpl.html
  17. *
  18. * @file
  19. */
  20. /**
  21. * Form to edit user preferences.
  22. *
  23. * @since 1.32
  24. */
  25. class PreferencesFormOOUI extends OOUIHTMLForm {
  26. // Override default value from HTMLForm
  27. protected $mSubSectionBeforeFields = false;
  28. /** @var User|null */
  29. private $modifiedUser;
  30. /** @var bool */
  31. private $privateInfoEditable = true;
  32. /** @var bool */
  33. private $optionsEditable = true;
  34. /**
  35. * @param User $user
  36. */
  37. public function setModifiedUser( $user ) {
  38. $this->modifiedUser = $user;
  39. }
  40. /**
  41. * @return User
  42. */
  43. public function getModifiedUser() {
  44. if ( $this->modifiedUser === null ) {
  45. return $this->getUser();
  46. } else {
  47. return $this->modifiedUser;
  48. }
  49. }
  50. /**
  51. * @return bool
  52. */
  53. public function isPrivateInfoEditable() {
  54. return $this->privateInfoEditable;
  55. }
  56. /**
  57. * Whether the
  58. * @param bool $editable
  59. */
  60. public function setPrivateInfoEditable( $editable ) {
  61. $this->privateInfoEditable = $editable;
  62. }
  63. /**
  64. * @return bool
  65. */
  66. public function areOptionsEditable() {
  67. return $this->optionsEditable;
  68. }
  69. /**
  70. * @param bool $optionsEditable
  71. */
  72. public function setOptionsEditable( $optionsEditable ) {
  73. $this->optionsEditable = $optionsEditable;
  74. }
  75. /**
  76. * Get extra parameters for the query string when redirecting after
  77. * successful save.
  78. *
  79. * @return array
  80. */
  81. public function getExtraSuccessRedirectParameters() {
  82. return [];
  83. }
  84. /**
  85. * @param string $html
  86. * @return string
  87. */
  88. function wrapForm( $html ) {
  89. $html = Xml::tags( 'div', [ 'id' => 'preferences' ], $html );
  90. return parent::wrapForm( $html );
  91. }
  92. /**
  93. * @return string
  94. */
  95. function getButtons() {
  96. if ( !$this->areOptionsEditable() && !$this->isPrivateInfoEditable() ) {
  97. return '';
  98. }
  99. $html = parent::getButtons();
  100. if ( $this->areOptionsEditable() ) {
  101. $t = $this->getTitle()->getSubpage( 'reset' );
  102. $html .= new OOUI\ButtonWidget( [
  103. 'infusable' => true,
  104. 'id' => 'mw-prefs-restoreprefs',
  105. 'label' => $this->msg( 'restoreprefs' )->text(),
  106. 'href' => $t->getLinkURL(),
  107. 'flags' => [ 'destructive' ],
  108. 'framed' => false,
  109. ] );
  110. $html = Xml::tags( 'div', [ 'class' => 'mw-prefs-buttons' ], $html );
  111. }
  112. return $html;
  113. }
  114. /**
  115. * Separate multi-option preferences into multiple preferences, since we
  116. * have to store them separately
  117. * @param array $data
  118. * @return array
  119. */
  120. function filterDataForSubmit( $data ) {
  121. foreach ( $this->mFlatFields as $fieldname => $field ) {
  122. if ( $field instanceof HTMLNestedFilterable ) {
  123. // @phan-suppress-next-next-line PhanUndeclaredProperty All HTMLForm fields have mParams,
  124. // but the instanceof confuses phan, which doesn't support intersections
  125. $info = $field->mParams;
  126. $prefix = $info['prefix'] ?? $fieldname;
  127. foreach ( $field->filterDataForSubmit( $data[$fieldname] ) as $key => $value ) {
  128. $data["$prefix$key"] = $value;
  129. }
  130. unset( $data[$fieldname] );
  131. }
  132. }
  133. return $data;
  134. }
  135. protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
  136. $layout = parent::wrapFieldSetSection( $legend, $section, $attributes, $isRoot );
  137. $layout->addClasses( [ 'mw-prefs-fieldset-wrapper' ] );
  138. $layout->removeClasses( [ 'oo-ui-panelLayout-framed' ] );
  139. return $layout;
  140. }
  141. /**
  142. * Get the whole body of the form.
  143. * @return string
  144. */
  145. function getBody() {
  146. $tabPanels = [];
  147. foreach ( $this->mFieldTree as $key => $val ) {
  148. if ( !is_array( $val ) ) {
  149. wfDebug( __METHOD__ . " encountered a field not attached to a section: '$key'" );
  150. continue;
  151. }
  152. $label = $this->getLegend( $key );
  153. $content =
  154. $this->getHeaderText( $key ) .
  155. $this->displaySection(
  156. $this->mFieldTree[$key],
  157. "",
  158. "mw-prefsection-$key-"
  159. ) .
  160. $this->getFooterText( $key );
  161. $tabPanels[] = new OOUI\TabPanelLayout( 'mw-prefsection-' . $key, [
  162. 'classes' => [ 'mw-htmlform-autoinfuse-lazy' ],
  163. 'label' => $label,
  164. 'content' => new OOUI\FieldsetLayout( [
  165. 'classes' => [ 'mw-prefs-section-fieldset' ],
  166. 'id' => "mw-prefsection-$key",
  167. 'label' => $label,
  168. 'items' => [
  169. new OOUI\Widget( [
  170. 'content' => new OOUI\HtmlSnippet( $content )
  171. ] ),
  172. ],
  173. ] ),
  174. 'expanded' => false,
  175. 'framed' => true,
  176. ] );
  177. }
  178. $indexLayout = new OOUI\IndexLayout( [
  179. 'infusable' => true,
  180. 'expanded' => false,
  181. 'autoFocus' => false,
  182. 'classes' => [ 'mw-prefs-tabs' ],
  183. ] );
  184. $indexLayout->addTabPanels( $tabPanels );
  185. return new OOUI\PanelLayout( [
  186. 'framed' => true,
  187. 'expanded' => false,
  188. 'classes' => [ 'mw-prefs-tabs-wrapper' ],
  189. 'content' => $indexLayout
  190. ] );
  191. }
  192. /**
  193. * Get the "<legend>" for a given section key. Normally this is the
  194. * prefs-$key message but we'll allow extensions to override it.
  195. * @param string $key
  196. * @return string
  197. */
  198. function getLegend( $key ) {
  199. $legend = parent::getLegend( $key );
  200. Hooks::run( 'PreferencesGetLegend', [ $this, $key, &$legend ] );
  201. return $legend;
  202. }
  203. /**
  204. * Get the keys of each top level preference section.
  205. * @return string[] List of section keys
  206. */
  207. function getPreferenceSections() {
  208. return array_keys( array_filter( $this->mFieldTree, 'is_array' ) );
  209. }
  210. }