MediaWiki master
getConfiguration.php
Go to the documentation of this file.
1<?php
14
15// @codeCoverageIgnoreStart
16require_once __DIR__ . '/Maintenance.php';
17// @codeCoverageIgnoreEnd
18
25
27 protected $regex = null;
28
30 protected $format = null;
31
33 protected $settings_list = [];
34
39 private const OUT_FORMATS = [
40 'json',
41 'php',
42 'serialize',
43 'vardump',
44 ];
45
46 public function __construct() {
47 parent::__construct();
48 $this->addDescription( 'Get serialized MediaWiki site configuration' );
49 $this->addOption( 'regex', 'regex to filter variables with', false, true );
50 $this->addOption( 'iregex', 'same as --regex but case insensitive', false, true );
51 $this->addOption( 'settings', 'Space-separated list of wg* variables', false, true );
52 $this->addOption( 'format', implode( ', ', self::OUT_FORMATS ), false, true );
53 $this->addOption(
54 'json-partial-output-on-error',
55 'Use JSON_PARTIAL_OUTPUT_ON_ERROR flag with json_encode(). This allows for partial response to ' .
56 'be output in case of an exception while serializing to JSON. If an error occurs, ' .
57 'the wgGetConfigurationJsonErrorOccurred field is set in the output.'
58 );
59 }
60
61 public function validateParamsAndArgs() {
62 $error_out = false;
63
64 # Get the format and make sure it is set to a valid default value
65 $this->format = strtolower( $this->getOption( 'format', 'PHP' ) );
66
67 $validFormat = in_array( $this->format, self::OUT_FORMATS );
68 if ( !$validFormat ) {
69 $this->error( "--format set to an unrecognized format" );
70 $error_out = true;
71 }
72
73 if ( $this->getOption( 'regex' ) && $this->getOption( 'iregex' ) ) {
74 $this->error( "Can only use either --regex or --iregex" );
75 $error_out = true;
76 }
77 $this->regex = $this->getOption( 'regex' ) ?: $this->getOption( 'iregex' );
78 if ( $this->regex ) {
79 $this->regex = '/' . $this->regex . '/';
80 if ( $this->hasOption( 'iregex' ) ) {
81 # case insensitive regex
82 $this->regex .= 'i';
83 }
84 }
85
86 if ( $this->hasOption( 'settings' ) ) {
87 $this->settings_list = explode( ' ', $this->getOption( 'settings' ) );
88 # Values validation
89 foreach ( $this->settings_list as $name ) {
90 if ( !preg_match( '/^wg[A-Z]/', $name ) ) {
91 $this->error( "Variable '$name' does start with 'wg'." );
92 $error_out = true;
93 } elseif ( !array_key_exists( $name, $GLOBALS ) ) {
94 $this->error( "Variable '$name' is not set." );
95 $error_out = true;
96 } elseif ( !$this->isAllowedVariable( $GLOBALS[$name] ) ) {
97 $this->error( "Variable '$name' includes non-array, non-scalar, items." );
98 $error_out = true;
99 }
100 }
101 }
102
103 parent::validateParamsAndArgs();
104
105 if ( $error_out ) {
106 # Force help and quit
107 $this->maybeHelp( true );
108 }
109 }
110
111 public function execute() {
112 // Settings we will display
113 $res = [];
114
115 # Default: dump any wg / wmg variable
116 if ( !$this->regex && !$this->getOption( 'settings' ) ) {
117 // Avoid fatal "Exception: Serialization of Closure is not allowed"
118 //
119 // * Exclude legacy singletons that are not configuration but
120 // non-serializable objects, such as $wgUser.
121 // * Exclude config arrays such as wgHooks which may contain closures
122 // via LocalSettings.php.
123 $this->regex = '/^wm?g(?!User|Out|Request|Hooks).*$/';
124 }
125
126 # Filter out globals based on the regex
127 if ( $this->regex ) {
128 foreach ( $GLOBALS as $name => $value ) {
129 if ( preg_match( $this->regex, $name ) ) {
130 $res[$name] = $value;
131 }
132 }
133 }
134
135 # Explicitly dumps a list of provided global names
136 if ( $this->settings_list ) {
137 foreach ( $this->settings_list as $name ) {
138 $res[$name] = $GLOBALS[$name];
139 }
140 }
141
142 ksort( $res );
143
144 switch ( $this->format ) {
145 case 'serialize':
146 case 'php':
147 $out = serialize( $res );
148 break;
149 case 'vardump':
150 $out = $this->formatVarDump( $res );
151 break;
152 case 'json':
153 $out = FormatJson::encode( $res );
154 if ( !$out && $this->getOption( 'json-partial-output-on-error' ) ) {
155 $res['wgGetConfigurationJsonErrorOccurred'] = true;
156 $out = json_encode( $res, JSON_PARTIAL_OUTPUT_ON_ERROR );
157 }
158 break;
159 default:
160 $this->fatalError( "Invalid serialization format given." );
161 }
162 if ( !is_string( $out ) ) {
163 $this->fatalError( "Failed to serialize the requested settings." );
164 }
165
166 if ( $out ) {
167 $this->output( $out . "\n" );
168 }
169 }
170
171 protected function formatVarDump( array $res ): string {
172 $ret = '';
173 foreach ( $res as $key => $value ) {
174 # intercept var_dump() output
175 ob_start();
176 print "\${$key} = ";
177 var_dump( $value );
178 # grab var_dump() output and discard it from the output buffer
179 $ret .= trim( ob_get_clean() ) . ";\n";
180 }
181
182 return trim( $ret, "\n" );
183 }
184
188 private function isAllowedVariable( $value ): bool {
189 if ( is_array( $value ) ) {
190 foreach ( $value as $v ) {
191 if ( !$this->isAllowedVariable( $v ) ) {
192 return false;
193 }
194 }
195
196 return true;
197 } elseif ( is_scalar( $value ) || $value === null ) {
198 return true;
199 }
200
201 return false;
202 }
203}
204
205// @codeCoverageIgnoreStart
206$maintClass = GetConfiguration::class;
207require_once RUN_MAINTENANCE_IF_MAIN;
208// @codeCoverageIgnoreEnd
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:68
Print serialized output of MediaWiki config vars.
execute()
Do the actual work.
formatVarDump(array $res)
__construct()
Default constructor.
validateParamsAndArgs()
Run some validation checks on the params, etc.
JSON formatter wrapper class.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
output( $out, $channel=null)
Throw some output to the user.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
hasOption( $name)
Checks to see if a particular option was set.
getOption( $name, $default=null)
Get an option, or return the default.
error( $err, $die=0)
Throw an error to the user.
maybeHelp( $force=false)
Maybe show the help.
addDescription( $text)
Set the description text.