wiki.techinc.nl/maintenance/CodeCleanerGlobalsPass.php

52 lines
1.8 KiB
PHP
Raw Normal View History

Drop in replacement of eval.php based on psysh eval.php is meant to eval() commands in MediaWiki global scope. We had at least a couple attempts to move it to a regular Maintenance script. As noted on the revert commit b475e930 r54839, using a Maintenance script drop us in the callee function scope instead of the global scope which is a hard requirement. http://psysh.org/ is a Read-Eval-Print-Loop with color highlight, modern code and more. Add maintenance/shell.php script as MediaWikiShell class. Passing command from stdin is supported. Execution is forked for graceful handling of PHP fatal errors. Colors!! Support the undocumented '-d' arguments from eval.php: 0 set $wgDebugLogFile to stdout. Eval.php used /dev/stdout, make it php://stdout in the new script. 1 additionally set DBO_DEBUG on all the database load balancer servers PHP globals have to be whitelisted which is not supported out of the box by Psy. Upon request, the author of PsySh, Justin Hileman, kindly provided a pass to inject globals (with the exceptions of super globals). He agreed for code reuse: https://github.com/bobthecow/psysh/issues/353 The code was added to maintenance/CodeCleanerGlobalsPass.inc Note that this is not a perfect simulation of global scope (but pretty close): variables declared in the shell which did not exist before won't be global unless the 'global' keword is used. Example usage: $ php maintenance/shell.php >>> $wgFullyInitialised => true >>> $hashar = User::newFromName( 'hashar' ) => User {#274 +mId: null, +mName: "Hashar", ... >>> ls --long --all $h <descriptive output of all object properties/methods> Bug: T117661 Signed-off-by: Justin Hileman <justin@justinhileman.info> Signed-off-by: Gergő Tisza <tgr.huwiki@gmail.com> Change-Id: I3d6d42e138d3cc4a0aaafdd7f5f97cb17d8b8cb3
2017-01-25 22:29:40 +00:00
<?php
/**
* Psy CodeCleaner to allow PHP super globals.
*
* https://github.com/bobthecow/psysh/issues/353
*
* Copyright © 2017 Justin Hileman <justin@justinhileman.info>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Maintenance
*
* @author Justin Hileman <justin@justinhileman.info>
*/
/**
* Prefix the real command with a bunch of 'global $VAR;' commands, one for each global.
* This will make the shell behave as if it was running in the global scope (almost;
* variables created in the shell won't become global if no global variable by that name
* existed before).
*/
class CodeCleanerGlobalsPass extends \Psy\CodeCleaner\CodeCleanerPass {
private static $superglobals = [
'GLOBALS', '_SERVER', '_ENV', '_FILES', '_COOKIE', '_POST', '_GET', '_SESSION'
];
public function beforeTraverse( array $nodes ) {
$names = [];
foreach ( array_diff( array_keys( $GLOBALS ), self::$superglobals ) as $name ) {
array_push( $names, new \PhpParser\Node\Expr\Variable( $name ) );
}
array_unshift( $nodes, new \PhpParser\Node\Stmt\Global_( $names ) );
return $nodes;
}
}