HTMLTitleTextField.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <?php
  2. use MediaWiki\Widget\TitleInputWidget;
  3. /**
  4. * Implements a text input field for page titles.
  5. * Automatically does validation that the title is valid,
  6. * as well as autocompletion if using the OOUI display format.
  7. *
  8. * Optional parameters:
  9. * 'namespace' - Namespace the page must be in
  10. * 'relative' - If true and 'namespace' given, strip/add the namespace from/to the title as needed
  11. * 'creatable' - Whether to validate the title is creatable (not a special page)
  12. * 'exists' - Whether to validate that the title already exists
  13. *
  14. * @since 1.26
  15. */
  16. class HTMLTitleTextField extends HTMLTextField {
  17. public function __construct( $params ) {
  18. $params += [
  19. 'namespace' => false,
  20. 'relative' => false,
  21. 'creatable' => false,
  22. 'exists' => false,
  23. // This overrides the default from HTMLFormField
  24. 'required' => true,
  25. ];
  26. parent::__construct( $params );
  27. }
  28. public function validate( $value, $alldata ) {
  29. // Default value (from getDefault()) is null, which breaks Title::newFromTextThrow() below
  30. if ( $value === null ) {
  31. $value = '';
  32. }
  33. if ( !$this->mParams['required'] && $value === '' ) {
  34. // If this field is not required and the value is empty, that's okay, skip validation
  35. return parent::validate( $value, $alldata );
  36. }
  37. try {
  38. if ( !$this->mParams['relative'] ) {
  39. $title = Title::newFromTextThrow( $value );
  40. } else {
  41. // Can't use Title::makeTitleSafe(), because it doesn't throw useful exceptions
  42. $title = Title::newFromTextThrow( Title::makeName( $this->mParams['namespace'], $value ) );
  43. }
  44. } catch ( MalformedTitleException $e ) {
  45. return $this->msg( $e->getErrorMessage(), $e->getErrorMessageParameters() );
  46. }
  47. $text = $title->getPrefixedText();
  48. if ( $this->mParams['namespace'] !== false &&
  49. !$title->inNamespace( $this->mParams['namespace'] )
  50. ) {
  51. return $this->msg( 'htmlform-title-badnamespace', $text, $this->mParams['namespace'] );
  52. }
  53. if ( $this->mParams['creatable'] && !$title->canExist() ) {
  54. return $this->msg( 'htmlform-title-not-creatable', $text );
  55. }
  56. if ( $this->mParams['exists'] && !$title->exists() ) {
  57. return $this->msg( 'htmlform-title-not-exists', $text );
  58. }
  59. return parent::validate( $value, $alldata );
  60. }
  61. protected function getInputWidget( $params ) {
  62. if ( $this->mParams['namespace'] !== false ) {
  63. $params['namespace'] = $this->mParams['namespace'];
  64. }
  65. $params['relative'] = $this->mParams['relative'];
  66. return new TitleInputWidget( $params );
  67. }
  68. protected function shouldInfuseOOUI() {
  69. return true;
  70. }
  71. protected function getOOUIModules() {
  72. // FIXME: TitleInputWidget should be in its own module
  73. return [ 'mediawiki.widgets' ];
  74. }
  75. public function getInputHtml( $value ) {
  76. // add mw-searchInput class to enable search suggestions for non-OOUI, too
  77. $this->mClass .= 'mw-searchInput';
  78. // return the HTMLTextField html
  79. return parent::getInputHTML( $value );
  80. }
  81. protected function getDataAttribs() {
  82. return [
  83. 'data-mw-searchsuggest' => FormatJson::encode( [
  84. 'wrapAsLink' => false,
  85. ] ),
  86. ];
  87. }
  88. }