Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 63 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
MWEval | |
0.00% |
0 / 60 |
|
0.00% |
0 / 3 |
462 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
2 | |||
canExecuteWithoutLocalSettings | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 44 |
|
0.00% |
0 / 1 |
380 |
1 | <?php |
2 | /** |
3 | * This script lets a command-line user start up the wiki engine and then poke |
4 | * about by issuing PHP commands directly. |
5 | * |
6 | * Unlike eg Python, you need to use a 'return' statement explicitly for the |
7 | * interactive shell to print out the value of the expression. Multiple lines |
8 | * are evaluated separately, so blocks need to be input without a line break. |
9 | * Fatal errors such as use of undeclared functions can kill the shell. |
10 | * |
11 | * To get decent line editing behavior, you should compile PHP with support |
12 | * for GNU readline (pass --with-readline to configure). |
13 | * |
14 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by |
16 | * the Free Software Foundation; either version 2 of the License, or |
17 | * (at your option) any later version. |
18 | * |
19 | * This program is distributed in the hope that it will be useful, |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 | * GNU General Public License for more details. |
23 | * |
24 | * You should have received a copy of the GNU General Public License along |
25 | * with this program; if not, write to the Free Software Foundation, Inc., |
26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
27 | * http://www.gnu.org/copyleft/gpl.html |
28 | * |
29 | * @file |
30 | * @ingroup Maintenance |
31 | */ |
32 | |
33 | use MediaWiki\HookContainer\HookRunner; |
34 | use MediaWiki\Logger\ConsoleSpi; |
35 | use MediaWiki\Logger\LoggerFactory; |
36 | use MediaWiki\MediaWikiServices; |
37 | |
38 | require_once __DIR__ . '/Maintenance.php'; |
39 | |
40 | /** |
41 | * Maintenance script providing an interactive console for evaluating php commands |
42 | * in the context of an initialized MediaWiki instance. |
43 | * |
44 | * @ingroup Maintenance |
45 | */ |
46 | // phpcs:disable MediaWiki.Files.ClassMatchesFilename.NotMatch |
47 | class MWEval extends Maintenance { |
48 | public function __construct() { |
49 | parent::__construct(); |
50 | $this->addDescription( |
51 | 'Maintenance script providing an interactive console for evaluating php' . |
52 | 'commands in the context of an initialized MediaWiki instance.' |
53 | ); |
54 | |
55 | $this->addOption( |
56 | 'd', |
57 | 'Enable (some) debug output', |
58 | false, |
59 | true |
60 | ); |
61 | |
62 | $this->addOption( |
63 | 'ignore-errors', |
64 | 'Ignore (some) errors' |
65 | ); |
66 | } |
67 | |
68 | public function canExecuteWithoutLocalSettings(): bool { |
69 | return true; |
70 | } |
71 | |
72 | public function execute() { |
73 | if ( $this->hasOption( 'd' ) ) { |
74 | $d = $this->getOption( 'd' ); |
75 | if ( $d > 0 ) { |
76 | LoggerFactory::registerProvider( new ConsoleSpi ); |
77 | // Some services hold Logger instances in object properties |
78 | MediaWikiServices::resetGlobalInstance(); |
79 | } |
80 | if ( $d > 1 ) { |
81 | $this->getServiceContainer()->getConnectionProvider()->getPrimaryDatabase()->setFlag( DBO_DEBUG ); |
82 | $this->getServiceContainer()->getConnectionProvider()->getReplicaDatabase()->setFlag( DBO_DEBUG ); |
83 | } |
84 | } |
85 | |
86 | // pull all globals into local scope |
87 | foreach ( $GLOBALS as $name => $unused ) { |
88 | // phpcs:disable MediaWiki.NamingConventions.ValidGlobalName.allowedPrefix |
89 | // phpcs:disable MediaWiki.VariableAnalysis.UnusedGlobalVariables.UnusedGlobal$name |
90 | global $$name; |
91 | } |
92 | |
93 | $__ignoreErrors = $this->hasOption( 'ignore-errors' ); |
94 | |
95 | $__useReadline = function_exists( 'readline_add_history' ) |
96 | && Maintenance::posix_isatty( 0 /*STDIN*/ ); |
97 | |
98 | if ( $__useReadline ) { |
99 | $__historyFile = isset( $_ENV['HOME'] ) ? |
100 | "{$_ENV['HOME']}/.mweval_history" : ( MW_INSTALL_PATH . "/maintenance/.mweval_history" ); |
101 | readline_read_history( $__historyFile ); |
102 | } else { |
103 | $__historyFile = null; |
104 | } |
105 | |
106 | ( new HookRunner( $this->getServiceContainer()->getHookContainer() ) )->onMaintenanceShellStart(); |
107 | |
108 | $__e = null; // PHP exception |
109 | while ( ( $__line = Maintenance::readconsole() ) !== false ) { |
110 | if ( !$__ignoreErrors && $__e && !preg_match( '/^(exit|die);?$/', $__line ) ) { |
111 | // Internal state may be corrupted or fatals may occur later due |
112 | // to some object not being set. Don't drop out of eval in case |
113 | // lines were being pasted in (which would then get dumped to the shell). |
114 | // Instead, just absorb the remaining commands. Let "exit" through per DWIM. |
115 | echo "Exception was thrown before; please restart eval.php\n"; |
116 | continue; |
117 | } |
118 | if ( $__useReadline ) { |
119 | readline_add_history( $__line ); |
120 | // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal |
121 | readline_write_history( $__historyFile ); |
122 | } |
123 | try { |
124 | // @phan-suppress-next-next-line SecurityCheck-RCE |
125 | // phpcs:ignore MediaWiki.Usage.ForbiddenFunctions.eval |
126 | $__val = eval( $__line . ";" ); |
127 | } catch ( Exception $__e ) { |
128 | fwrite( STDERR, "Caught exception " . get_class( $__e ) . |
129 | ": {$__e->getMessage()}\n" . $__e->getTraceAsString() . "\n" ); |
130 | continue; |
131 | } catch ( Throwable $__e ) { |
132 | if ( $__ignoreErrors ) { |
133 | fwrite( STDERR, "Caught " . get_class( $__e ) . |
134 | ": {$__e->getMessage()}\n" . $__e->getTraceAsString() . "\n" ); |
135 | continue; |
136 | } else { |
137 | throw $__e; |
138 | } |
139 | } |
140 | if ( $__val === null ) { |
141 | echo "\n"; |
142 | } elseif ( is_string( $__val ) || is_numeric( $__val ) ) { |
143 | echo "$__val\n"; |
144 | } else { |
145 | var_dump( $__val ); |
146 | } |
147 | } |
148 | |
149 | echo "\n"; |
150 | } |
151 | } |
152 | |
153 | $maintClass = MWEval::class; |
154 | require_once RUN_MAINTENANCE_IF_MAIN; |