File: HTMLTitleTextField.php

package info (click to toggle)
mediawiki 1%3A1.43.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 417,464 kB
  • sloc: php: 1,062,949; javascript: 664,290; sql: 9,714; python: 5,458; xml: 3,489; sh: 1,131; makefile: 64
file content (135 lines) | stat: -rw-r--r-- 4,425 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?php

namespace MediaWiki\HTMLForm\Field;

use InvalidArgumentException;
use MediaWiki\Json\FormatJson;
use MediaWiki\MediaWikiServices;
use MediaWiki\Title\MalformedTitleException;
use MediaWiki\Title\Title;
use MediaWiki\Widget\TitleInputWidget;

/**
 * Implements a text input field for page titles.
 * Automatically does validation that the title is valid,
 * as well as autocompletion if using the OOUI display format.
 *
 * Optional parameters:
 * 'namespace' - Namespace the page must be in (use namespace constant; one of the NS_* constants may be used)
 * 'relative' - If true and 'namespace' given, strip/add the namespace from/to the title as needed
 * 'creatable' - Whether to validate the title is creatable (not a special page)
 * 'exists' - Whether to validate that the title already exists
 * 'interwiki' – Tolerate interwiki links (other conditions such as 'namespace' or 'exists' will be
 *   ignored if the title is an interwiki title). Cannot be used together with 'relative'.
 *
 * @stable to extend
 * @since 1.26
 */
class HTMLTitleTextField extends HTMLTextField {
	/**
	 * @stable to call
	 * @inheritDoc
	 */
	public function __construct( $params ) {
		$params += [
			'namespace' => false,
			'relative' => false,
			'creatable' => false,
			'exists' => false,
			'interwiki' => false,
			// This overrides the default from HTMLFormField
			'required' => true,
		];

		parent::__construct( $params );
	}

	public function validate( $value, $alldata ) {
		if ( $this->mParams['interwiki'] && $this->mParams['relative'] ) {
			// relative and interwiki cannot be used together, because we don't have a way to know about
			// namespaces used by the other wiki (and it might actually be a non-wiki link, too).
			throw new InvalidArgumentException( 'relative and interwiki may not be used together' );
		}
		// Default value (from getDefault()) is null, which breaks Title::newFromTextThrow() below
		$value ??= '';

		if ( !$this->mParams['required'] && $value === '' ) {
			// If this field is not required and the value is empty, that's okay, skip validation
			return parent::validate( $value, $alldata );
		}

		$titleFactory = MediaWikiServices::getInstance()->getTitleFactory();
		try {
			if ( !$this->mParams['relative'] ) {
				$title = $titleFactory->newFromTextThrow( $value );
			} else {
				// Can't use makeTitleSafe(), because it doesn't throw useful exceptions
				$title = $titleFactory->newFromTextThrow( Title::makeName( $this->mParams['namespace'], $value ) );
			}
		} catch ( MalformedTitleException $e ) {
			return $this->msg( $e->getErrorMessage(), $e->getErrorMessageParameters() );
		}

		if ( $title->isExternal() ) {
			if ( $this->mParams['interwiki'] ) {
				// We cannot validate external titles, skip the rest of the validation
				return parent::validate( $value, $alldata );
			} else {
				return $this->msg( 'htmlform-title-interwiki', $title->getPrefixedText() );
			}
		}

		$text = $title->getPrefixedText();
		if ( $this->mParams['namespace'] !== false &&
			!$title->inNamespace( $this->mParams['namespace'] )
		) {
			return $this->msg( 'htmlform-title-badnamespace', $text, $this->mParams['namespace'] );
		}

		if ( $this->mParams['creatable'] && !$title->canExist() ) {
			return $this->msg( 'htmlform-title-not-creatable', $text );
		}

		if ( $this->mParams['exists'] && !$title->exists() ) {
			return $this->msg( 'htmlform-title-not-exists', $text );
		}

		return parent::validate( $value, $alldata );
	}

	protected function getInputWidget( $params ) {
		if ( $this->mParams['namespace'] !== false ) {
			$params['namespace'] = $this->mParams['namespace'];
		}
		$params['relative'] = $this->mParams['relative'];
		return new TitleInputWidget( $params );
	}

	protected function shouldInfuseOOUI() {
		return true;
	}

	protected function getOOUIModules() {
		// FIXME: TitleInputWidget should be in its own module
		return [ 'mediawiki.widgets' ];
	}

	public function getInputHtml( $value ) {
		// add mw-searchInput class to enable search suggestions for non-OOUI, too
		$this->mClass .= 'mw-searchInput';

		// return the HTMLTextField html
		return parent::getInputHTML( $value );
	}

	protected function getDataAttribs() {
		return [
			'data-mw-searchsuggest' => FormatJson::encode( [
				'wrapAsLink' => false,
			] ),
		];
	}
}

/** @deprecated class alias since 1.42 */
class_alias( HTMLTitleTextField::class, 'HTMLTitleTextField' );