Index: trunk/phase3/maintenance/Maintenance.php |
— | — | @@ -98,6 +98,7 @@ |
99 | 99 | */ |
100 | 100 | public function __construct() { |
101 | 101 | $this->addDefaultParams(); |
| 102 | + register_shutdown_function( array( $this, 'outputChanneled' ), false ); |
102 | 103 | } |
103 | 104 | |
104 | 105 | /** |
— | — | @@ -214,14 +215,14 @@ |
215 | 216 | * Throw some output to the user. Scripts can call this with no fears, |
216 | 217 | * as we handle all --quiet stuff here |
217 | 218 | * @param $out String The text to show to the user |
| 219 | + * @param $channel Mixed Unique identifier for the channel. See function outputChanneled. |
218 | 220 | */ |
219 | | - protected function output( $out ) { |
| 221 | + protected function output( $out, $channel = null ) { |
220 | 222 | if( $this->mQuiet ) { |
221 | 223 | return; |
222 | 224 | } |
223 | | - $f = fopen( 'php://stdout', 'w' ); |
224 | | - fwrite( $f, $out ); |
225 | | - fclose( $f ); |
| 225 | + $out = preg_replace( '/\n\z/', '', $out ); |
| 226 | + $this->outputChanneled( $out, $channel ); |
226 | 227 | } |
227 | 228 | |
228 | 229 | /** |
— | — | @@ -231,6 +232,7 @@ |
232 | 233 | * @param $die boolean If true, go ahead and die out. |
233 | 234 | */ |
234 | 235 | protected function error( $err, $die = false ) { |
| 236 | + $this->outputChanneled( false ); |
235 | 237 | if ( php_sapi_name() == 'cli' ) { |
236 | 238 | fwrite( STDERR, $err . "\n" ); |
237 | 239 | } else { |
— | — | @@ -241,7 +243,46 @@ |
242 | 244 | if( $die ) die(); |
243 | 245 | } |
244 | 246 | |
| 247 | + private $atLineStart = true; |
| 248 | + private $lastChannel = null; |
| 249 | + |
245 | 250 | /** |
| 251 | + * Message outputter with channeled message support. Messages on the |
| 252 | + * same channel are concatenated, but any intervening messages in another |
| 253 | + * channel start a new line. |
| 254 | + * @param $msg String The message without trailing newline |
| 255 | + * @param $channel Channel identifier or null for no channel. Channel comparison uses ===. |
| 256 | + */ |
| 257 | + public function outputChanneled( $msg, $channel = null ) { |
| 258 | + $handle = fopen( 'php://stdout', 'w' ); |
| 259 | + |
| 260 | + if ( $msg === false ) { |
| 261 | + // For cleanup |
| 262 | + if ( !$this->atLineStart ) fwrite( $handle, "\n" ); |
| 263 | + fclose( $handle ); |
| 264 | + return; |
| 265 | + } |
| 266 | + |
| 267 | + // End the current line if necessary |
| 268 | + if ( !$this->atLineStart && $channel !== $this->lastChannel ) { |
| 269 | + fwrite( $handle, "\n" ); |
| 270 | + } |
| 271 | + |
| 272 | + fwrite( $handle, $msg ); |
| 273 | + |
| 274 | + $this->atLineStart = false; |
| 275 | + if ( $channel === null ) { |
| 276 | + // For unchanneled messages, output trailing newline immediately |
| 277 | + fwrite( $handle, "\n" ); |
| 278 | + $this->atLineStart = true; |
| 279 | + } |
| 280 | + $this->lastChannel = $channel; |
| 281 | + |
| 282 | + // Cleanup handle |
| 283 | + fclose( $handle ); |
| 284 | + } |
| 285 | + |
| 286 | + /** |
246 | 287 | * Does the script need different DB access? By default, we give Maintenance |
247 | 288 | * scripts normal rights to the DB. Sometimes, a script needs admin rights |
248 | 289 | * access for a reason and sometimes they want no access. Subclasses should |