MediaWiki  master
SubmoduleDef.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use ApiBase;
7 use Html;
9 
17 class SubmoduleDef extends EnumDef {
18 
25  public const PARAM_SUBMODULE_MAP = 'param-submodule-map';
26 
31  public const PARAM_SUBMODULE_PARAM_PREFIX = 'param-submodule-param-prefix';
32 
33  public function checkSettings( string $name, $settings, array $options, array $ret ) : array {
34  $map = $settings[self::PARAM_SUBMODULE_MAP] ?? [];
35  if ( !is_array( $map ) ) {
36  $ret['issues'][self::PARAM_SUBMODULE_MAP] = 'PARAM_SUBMODULE_MAP must be an array, got '
37  . gettype( $map );
38  // Prevent errors in parent::checkSettings()
39  $settings[self::PARAM_SUBMODULE_MAP] = null;
40  }
41 
42  $ret = parent::checkSettings( $name, $settings, $options, $ret );
43 
44  $ret['allowedKeys'] = array_merge( $ret['allowedKeys'], [
45  self::PARAM_SUBMODULE_MAP, self::PARAM_SUBMODULE_PARAM_PREFIX,
46  ] );
47 
48  if ( is_array( $map ) ) {
49  $module = $options['module'];
50  foreach ( $map as $k => $v ) {
51  if ( !is_string( $v ) ) {
52  $ret['issues'][] = 'Values for PARAM_SUBMODULE_MAP must be strings, '
53  . "but value for \"$k\" is " . gettype( $v );
54  continue;
55  }
56 
57  try {
58  $submod = $module->getModuleFromPath( $v );
59  } catch ( ApiUsageException $ex ) {
60  $submod = null;
61  }
62  if ( !$submod ) {
63  $ret['issues'][] = "PARAM_SUBMODULE_MAP contains \"$v\", which is not a valid module path";
64  }
65  }
66  }
67 
68  if ( !is_string( $settings[self::PARAM_SUBMODULE_PARAM_PREFIX] ?? '' ) ) {
69  $ret['issues'][self::PARAM_SUBMODULE_PARAM_PREFIX] = 'PARAM_SUBMODULE_PARAM_PREFIX must be '
70  . 'a string, got ' . gettype( $settings[self::PARAM_SUBMODULE_PARAM_PREFIX] );
71  }
72 
73  return $ret;
74  }
75 
76  public function getEnumValues( $name, array $settings, array $options ) {
77  if ( isset( $settings[self::PARAM_SUBMODULE_MAP] ) ) {
78  $modules = array_keys( $settings[self::PARAM_SUBMODULE_MAP] );
79  } else {
80  $modules = $options['module']->getModuleManager()->getNames( $name );
81  }
82 
83  return $modules;
84  }
85 
86  public function getParamInfo( $name, array $settings, array $options ) {
87  $info = parent::getParamInfo( $name, $settings, $options );
89  $module = $options['module'];
90 
91  if ( isset( $settings[self::PARAM_SUBMODULE_MAP] ) ) {
92  $info['type'] = array_keys( $settings[self::PARAM_SUBMODULE_MAP] );
93  $info['submodules'] = $settings[self::PARAM_SUBMODULE_MAP];
94  } else {
95  $info['type'] = $module->getModuleManager()->getNames( $name );
96  $prefix = $module->isMain() ? '' : ( $module->getModulePath() . '+' );
97  $info['submodules'] = [];
98  foreach ( $info['type'] as $v ) {
99  $info['submodules'][$v] = $prefix . $v;
100  }
101  }
102  if ( isset( $settings[self::PARAM_SUBMODULE_PARAM_PREFIX] ) ) {
103  $info['submoduleparamprefix'] = $settings[self::PARAM_SUBMODULE_PARAM_PREFIX];
104  }
105 
106  $submoduleFlags = []; // for sorting: higher flags are sorted later
107  $submoduleNames = []; // for sorting: lexicographical, ascending
108  foreach ( $info['submodules'] as $v => $submodulePath ) {
109  try {
110  $submod = $module->getModuleFromPath( $submodulePath );
111  } catch ( ApiUsageException $ex ) {
112  $submoduleFlags[] = 0;
113  $submoduleNames[] = $v;
114  continue;
115  }
116  $flags = 0;
117  if ( $submod && $submod->isDeprecated() ) {
118  $info['deprecatedvalues'][] = $v;
119  $flags |= 1;
120  }
121  if ( $submod && $submod->isInternal() ) {
122  $info['internalvalues'][] = $v;
123  $flags |= 2;
124  }
125  $submoduleFlags[] = $flags;
126  $submoduleNames[] = $v;
127  }
128  // sort $info['submodules'] and $info['type'] by $submoduleFlags and $submoduleNames
129  array_multisort( $submoduleFlags, $submoduleNames, $info['submodules'], $info['type'] );
130  if ( isset( $info['deprecatedvalues'] ) ) {
131  sort( $info['deprecatedvalues'] );
132  }
133  if ( isset( $info['internalvalues'] ) ) {
134  sort( $info['internalvalues'] );
135  }
136 
137  return $info;
138  }
139 
140  private function getSubmoduleMap( ApiBase $module, string $name, array $settings ) : array {
141  if ( isset( $settings[self::PARAM_SUBMODULE_MAP] ) ) {
142  $map = $settings[self::PARAM_SUBMODULE_MAP];
143  } else {
144  $prefix = $module->isMain() ? '' : ( $module->getModulePath() . '+' );
145  $map = [];
146  foreach ( $module->getModuleManager()->getNames( $name ) as $submoduleName ) {
147  $map[$submoduleName] = $prefix . $submoduleName;
148  }
149  }
150 
151  return $map;
152  }
153 
154  protected function sortEnumValues(
155  string $name, array $values, array $settings, array $options
156  ) : array {
157  $module = $options['module'];
158  $map = $this->getSubmoduleMap( $module, $name, $settings );
159 
160  $submoduleFlags = []; // for sorting: higher flags are sorted later
161  foreach ( $values as $k => $v ) {
162  $flags = 0;
163  try {
164  $submod = isset( $map[$v] ) ? $module->getModuleFromPath( $map[$v] ) : null;
165  if ( $submod && $submod->isDeprecated() ) {
166  $flags |= 1;
167  }
168  if ( $submod && $submod->isInternal() ) {
169  $flags |= 2;
170  }
171  } catch ( ApiUsageException $ex ) {
172  // Ignore
173  }
174  $submoduleFlags[$k] = $flags;
175  }
176  array_multisort( $submoduleFlags, $values, SORT_NATURAL );
177 
178  return $values;
179  }
180 
181  protected function getEnumValuesForHelp( $name, array $settings, array $options ) {
182  $module = $options['module'];
183  $map = $this->getSubmoduleMap( $module, $name, $settings );
184  $defaultAttrs = [ 'dir' => 'ltr', 'lang' => 'en' ];
185 
186  $values = [];
187  $submoduleFlags = []; // for sorting: higher flags are sorted later
188  $submoduleNames = []; // for sorting: lexicographical, ascending
189  foreach ( $map as $v => $m ) {
190  $attrs = $defaultAttrs;
191  $flags = 0;
192  try {
193  $submod = $module->getModuleFromPath( $m );
194  if ( $submod && $submod->isDeprecated() ) {
195  $attrs['class'][] = 'apihelp-deprecated-value';
196  $flags |= 1;
197  }
198  if ( $submod && $submod->isInternal() ) {
199  $attrs['class'][] = 'apihelp-internal-value';
200  $flags |= 2;
201  }
202  } catch ( ApiUsageException $ex ) {
203  // Ignore
204  }
205  $v = Html::element( 'span', $attrs, $v );
206  $values[] = "[[Special:ApiHelp/{$m}|{$v}]]";
207  $submoduleFlags[] = $flags;
208  $submoduleNames[] = $v;
209  }
210  // sort $values by $submoduleFlags and $submoduleNames
211  array_multisort( $submoduleFlags, $submoduleNames, SORT_NATURAL, $values, SORT_NATURAL );
212 
213  return $values;
214  }
215 
216 }
ApiUsageException
Exception used to abort API execution with an error.
Definition: ApiUsageException.php:29
MediaWiki\Api\Validator\SubmoduleDef\sortEnumValues
sortEnumValues(string $name, array $values, array $settings, array $options)
Sort enum values for help/param info output.
Definition: SubmoduleDef.php:154
Wikimedia\ParamValidator\TypeDef\EnumDef
Type definition for enumeration types.
Definition: EnumDef.php:32
MediaWiki\Api\Validator\SubmoduleDef\getEnumValuesForHelp
getEnumValuesForHelp( $name, array $settings, array $options)
Return enum values formatted for the help message.
Definition: SubmoduleDef.php:181
MediaWiki\Api\Validator\SubmoduleDef\PARAM_SUBMODULE_MAP
const PARAM_SUBMODULE_MAP
(string[]) Map parameter values to submodule paths.
Definition: SubmoduleDef.php:25
MediaWiki\Api\Validator\SubmoduleDef\checkSettings
checkSettings(string $name, $settings, array $options, array $ret)
Validate a parameter settings array.
Definition: SubmoduleDef.php:33
ApiBase\isMain
isMain()
Returns true if this module is the main module ($this === $this->mMainModule), false otherwise.
Definition: ApiBase.php:469
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:52
ApiBase\getModulePath
getModulePath()
Get the path to this module.
Definition: ApiBase.php:509
$modules
$modules
Definition: HTMLFormElement.php:15
MediaWiki\Api\Validator\SubmoduleDef\PARAM_SUBMODULE_PARAM_PREFIX
const PARAM_SUBMODULE_PARAM_PREFIX
(string) Used to indicate the 'g' prefix added by ApiQueryGeneratorBase (and similar if anything else...
Definition: SubmoduleDef.php:31
MediaWiki\Api\Validator\SubmoduleDef\getSubmoduleMap
getSubmoduleMap(ApiBase $module, string $name, array $settings)
Definition: SubmoduleDef.php:140
MediaWiki\Api\Validator
Definition: ApiParamValidator.php:3
ApiBase\getModuleManager
getModuleManager()
Get the module manager, or null if this module has no sub-modules.
Definition: ApiBase.php:252
MediaWiki\Api\Validator\SubmoduleDef\getParamInfo
getParamInfo( $name, array $settings, array $options)
Describe parameter settings in a machine-readable format.
Definition: SubmoduleDef.php:86
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
MediaWiki\Api\Validator\SubmoduleDef\getEnumValues
getEnumValues( $name, array $settings, array $options)
Get the values for enum-like parameters.
Definition: SubmoduleDef.php:76
MediaWiki\Api\Validator\SubmoduleDef
Type definition for submodule types.
Definition: SubmoduleDef.php:17
Html
This class is a collection of static functions that serve two purposes:
Definition: Html.php:49